Command-line PHP on QNAP hardware

免费体验120秒视频QNAP network-attached storage devices run a lightweight Linux derivative. It’s not a fully-functional Linux (specifically, it can’t update itself from the command line), but a lot of “Linuxy” things are possible nevertheless. Specifically, it is possible to run PHP from the command line, as long as you take care to either refer to the PHP executable by its full path or add its location to 免费体验120秒视频.

免费体验120秒视频On my HS-210, the PHP executable resides in?/mnt/ext/opt/apache/bin. To verify which executable it is, I ran the following command:

/mnt/ext/opt/apache/bin/php -r "echo php_sapi_name();"

which returned


This signifies that the executable is the command-line (CLI) executable rather than the CGI executable.

Battery report on Windows 10

Windows 10 has a command-line feature that generates a report on the condition of the battery. To generate the report, open the command line as administrator and type:

powercfg /batteryreport

The OS will generate the report as a viewable HTML file and output its location to screen:

C:\WINDOWS\system32>powercfg /batteryreportBattery life report saved to file path  C:\WINDOWS\system32\battery-report.html.

Canons of good spin

Dan Dennet’s canons of good spin (heard in Reverse-engineering Religion):

  • It is not a bare-faced lie
  • You have to be able to say it with a straight face
  • It has to relieve skepticism without arousing curiosity
  • It should seem profound

Finding system information on Windows

In practical system administration, it is sometimes necessary to record edition and/or version of Windows along with the product key (for example, before installing a non-Windows OS with the view of using the Windows product key on a different machine). This can be accomplished by using systeminfo and piping its output to findstr:

systeminfo | findstr /B /C:"OS Name" /C:"OS Version"

This will output the requested data fields in a format similar to this:

OS Name: Microsoft Windows 10 HomeOS Version:10.0.14393 N/A Build 14393

To display Windows 8.1 or Windows 10 product key, use wmic:

wmic path softwarelicensingservice get OA3xOriginalProductKey

Needless to say, all of the above has to be done while running the command line interpreter with administrative privileges.

Dealing with a c-state bug

Computers that run Linux (especially newer kernel versions) on Intel Bay Trail family processors are sometimes affected by a c-state bug. It manifests as a random and total freeze of the system. Screen content remains unchanged, but the machine becomes completely unresponsive. I have encountered this on units that run Intel Celeron N2920, but other members of the Bay Trail family can also be affected. Also, the? page linked to above suggests that the bug exists in kernel versions?3.16-4.2, but I have encountered it on Ubuntu 16.04 (kernel version 4.4) and Ubuntu 16.10 (kernel version 4.8), so this bug, as far as I can see, is still extant.

The freeze happens when the processor receives an instruction to enter an unsupported sleep state. The workaround, therefore, is to tell the kernel to stop giving those instructions to the processor. This is accomplished by editing the grub configuration file.

Open the grub configuration file for editing as root using your favorite editor. For example, assuming you’re using nano and are not logged in as root, you can type this into the terminal:

sudo nano /etc/default/grub

When the file opens, find the line that starts with GRUB_CMDLINE_LINUX_DEFAULT and change it to include intel_idle.max_cstate=1. Typically, after you’re done editing, the line would look like this:

GRUB_CMDLINE_LINUX_DEFAULT="quiet splash intel_idle.max_cstate=1"

The values quiet and splash are usually set by default and should be left in place.

Save the file (Ctrl+o, then Enter), exit (Ctrl+x), and apply the update:

sudo update-grub

Finally, restart the system.

Managing Windows product keys

Windows includes a little-known utility named slmgr (which presumably stands for Software License ManaGeR) that allows the administrator to install and uninstall Windows product keys (may be useful when upgrading). Both installation and uninstallation have to be done from the command line running as Administrator.

Uninstallation is done in two steps. First, the administrator needs to display values associated with the currently installed key:

slmgr /dlv

When this command is complete, Windows shows a message box showing a series of values associated with the currently installed product key, including Activation ID. The?Activation ID (a series of numbers, letters, and dashes) is used in the second step:

slmgr /upk [Activation ID goes here]

If everything went well, Windows will show a message box saying Uninstalled product key successfully.

Product key installation is a simpler single-step procedure:


The Xs, of course, represent the product key. If everything went well, Windows displays a message box saying Installed product key XXXXX-XXXXX-XXXXX-XXXXX-XXXXX successfully.

To display values returned by slmgr?in the console, rather than in a message?box, or save them into a text file, use cscript. For example:

cscript slmgr.vbs /dlvcscript slmgr.vbs /dlv > C:\Users\Public\licinfo.txt

The first command will display output in the console, the second, save it into the specified text file.

Predictors of hard drive failure

From the ever so helpful people at Backblaze:

For the last few years we’ve used the following five SMART stats as a means of helping determine if a drive is going to fail.

SMART 5Reallocated Sectors Count
SMART 187Reported Uncorrectable Errors
SMART 188Command Timeout
SMART 197Current Pending Sector Count
SMART 198Uncorrectable Sector Count

When the RAW value for one of these five attributes is greater than zero, we have a reason to investigate. We also monitor RAID array status, Backblaze Vault array status and other Backblaze internal logs to identify potential drive problems. These tools generally only report exceptions, so on any given day the number of investigations is manageable even though we have nearly 70,000 drives.

GPS and relativity

In order for GPS to work correctly, the software must explicitly take into account both special relativity and general relativity.

Adjustment for special relativity is needed because satellites fly around the Earth at approximately 8 km/s, which by itself results in time aboard a satellite flowing about 7 microseconds per day slower compared to time on Earth.

Adjustment for general relativity is due to the fact that GPS satellites orbit at a distance from Earth, where its gravitational pull is somewhat weaker compared to that on the Earth’s surface. This (again, by itself) leads to time aboard a satellite flowing approximately 45 microseconds per day faster compared to time at the sea level.

(Source: public lecture by Barry Barish at the Fermilab)

Literature: fantasy vs. realism

…judged by the standards of fantasy, modernist realist fiction,?with its narrow focus on daily details of contemporary human?affairs, is suffocating and unimaginative, almost unavoidably?trivial, and ominously anthropocentric.

(Ursula K. Le Guin, The Critics, the Monsters, and the Fantasists)

Getting Yahoo! Finance data into Excel

Here’s a little VBA snippet that allows to retrieve Yahoo! Finance data into an Excel spreadsheet.


=yfQuote(ticker, date, field), where

  • ticker (required)?is?ticker symbol used by Yahoo! Finance. Examples: MSFT, ^GSPC, VXX.
  • date (optional) is the date for which quotes are sought. If omitted, the most recent available historical quote is retrieved. Example: DATE(2014, 10, 11).
  • field (optional) is the data field requested. If omitted, close price is returned. Allowed values:?1 (open price),?2 (high price),?3 (low price),?4 (сlose price),?5 (volume), and?6 (adjusted close price).
Public Function yfQuote(strTicker As String, _Optional dtDate As Variant, _Optional intField As Variant)' dtDate is optional. If omitted, use today. ' If value is not a date, throw an error.If IsMissing(dtDate) ThendtDate = DateElseIf Not (IsDate(dtDate)) ThenyfQuote = CVErr(xlErrNum)End IfEnd If' intField is optional. ' If omitted, use 4 to retrieve closing price.If IsMissing(intField) ThenintField = 4ElseIf Not (IsNumeric(intField)) _ Or (intField > 6) _  Or (intField < 0) ThenyfQuote = CVErr(xlErrNum)End IfEnd IfDim dtStartDate As DateDim strURL As String Dim strCSV As String Dim strRows() As String Dim strColumns() As StringDim dblResult As DoubledtStartDate = dtDate - 7' Compose the request URL with start date and end datestrURL = "" & _ strTicker & _"&a=" & Month(dtStartDate) - 1 & _"&b=" & Day(dtStartDate) & _"&c=" & Year(dtStartDate) & _"&d=" & Month(dtDate) - 1 & _"&e=" & Day(dtDate) & _"&f=" & Year(dtDate) & _"&g=d&ignore=.csv"Set objHTTP = CreateObject("MSXML2.XMLHTTP")objHTTP.Open "GET", strURL, FalseobjHTTP.SendstrCSV = objHTTP.responseText' The most recent price information is in the second row; ' the first row is the table headings.' Order of fields:' 0 -- Date' 1 -- Open' 2 -- High' 3 -- Low' 4 -- Close' 5 -- Volume' 6 -- Adj Close' split the CSV into rowsstrRows() = Split(strCSV, Chr(10)) ' split the most recent row into columnsstrColumns = Split(strRows(1), ",") dblResult = strColumns(intField)yfQuote = dblResultSet objHTTP = NothingEnd Function


  1. Yahoo! Finance doesn’t allow retrieval of historical prices for currencies, so this function wouldn’t work with currency tickers such as USDEUR=X.
  2. With some additional fiddling, the function could be persuaded to accept 0 to return the date for which quotes are retrieved. This could be useful when retrieving the most recent quote. As is, this wouldn’t work because of?dblResult = strColumns(intField) (double value is expected, but a string is returned; there would have to be a conversion of that string into a date value)…