How to Use and Execute PHP Codes in Linux Command Line – Part 1
PHP is an open source server side scripting Language which originally stood for ‘Personal Home Page‘ now stands for ‘PHP: Hypertext Preprocessor‘, which is a recursive acronym. It is a cross platform scripting language which is highly influenced by C, C++ and Java.
Run PHP Codes in Linux Command Line – Part 1
A PHP Syntax is very similar to Syntax in C, Java and Perl Programming Language with a few PHP-specific feature. PHP is used by some 260 Million websites, as of now. The current stable release is PHP Version 5.6.10.
PHP is HTML embedded script which facilitates developers to write dynamically generated pages quickly. PHP is primarily used on Server-side (and JavaScript on Client Side) to generate dynamic web pages over HTTP, however you will be surprised to know that you can execute a PHP in a Linux Terminal without the need of a web browser.
This article aims at throwing light on the command-line aspect of PHP scripting Language.
1. After PHP and Apache2 installation, we need to install PHP command Line Interpreter.
Next thing, we do is to test a php (if installed correctly or not) commonly as by creating a file infophp.php at location ‘/var/www/html‘ (Apache2 working directory in most of the distros), with the content , simply by running the below command.
and then point your browser to http://127.0.0.1/infophp.php which opens this file in web browser.
Check PHP Info
Same results can be obtained from the Linux terminal without the need of any browser. Run the PHP file located at ‘/var/www/html/infophp.php‘ in Linux Command Line as:
Check PHP info from Commandline
Since the output is too big we can pipeline the above output with ‘less‘ command to get one screen output at a time, simply as:
Check All PHP Info
Here Option ‘-f‘ parse and execute the file that follows the command.
2. We can use phpinfo() which is a very valuable debugging tool directly on the Linux command-line without the need of calling it from a file, simply as:
PHP Debugging Tool
Here the option ‘-r‘ run the PHP Code in the Linux Terminal directly without tags and > .
3. Run PHP in Interactive mode and do some mathematics. Here option ‘-a‘ is for running PHP in Interactive Mode.
Press ‘exit‘ or ‘ctrl+c‘ to close PHP interactive mode.
Enable PHP Interactive Mode
4. You can run a PHP script simply as, if it is a shell script. First Create a PHP sample script in your current working directory.
Notice we used #!/usr/bin/php in the first line of this PHP script as we use to do in shell script (/bin/bash). The first line #!/usr/bin/php tells the Linux Command-Line to parse this script file to PHP Interpreter.
Second make it executable as:
5. You will be surprised to know you can create simple functions all by yourself using the interactive shell. Here is the step-by step instruction.
Start PHP interactive mode.
Create a function and name it addition. Also declare two variables $a and $b.
Use curly braces to define rules in between them for this function.
Define Rule(s). Here the rule say to add the two variables.
All rules defined. Enclose rules by closing curly braces.
Test function and add digits 4 and 3 simply as :
Sample Output
You may run the below code to execute the function, as many times as you want with different values. Replace a and b with values of yours.
Sample Output
You may run this function till you quit interactive mode (Ctrl+z). Also you would have noticed that in the above output the data type returned is NULL. This can be fixed by asking php interactive shell to return in place of echo.
Simply replace the ‘echo‘ statement in the above function with ‘return‘
and rest of the things and principles remain same.
Here is an Example, which returns appropriate data-type in the output.
PHP Functions
Always Remember, user defined functions are not saved in history from shell session to shell session, hence once you exit the interactive shell, it is lost.
Hope you liked this session. Keep Connected for more such posts. Stay Tuned and Healthy. Provide us with your valuable feedback in the comments. Like ans share us and help us get spread.
If You Appreciate What We Do Here On TecMint, You Should Consider:
TecMint is the fastest growing and most trusted community site for any kind of Linux Articles, Guides and Books on the web. Millions of people visit TecMint! to search or browse the thousands of published articles available FREELY to all.
If you like what you are reading, please consider buying us a coffee ( or 2 ) as a token of appreciation.
We are thankful for your never ending support.
Источник
shell_exec
(PHP 4, PHP 5, PHP 7, PHP 8)
shell_exec — Выполнить команду через оболочку и вернуть вывод в виде строки
Описание
Функция идентична оператору с обратным апострофом.
В Windows нижележащий канал открывается в текстовом режиме, что может привести к сбою функции для двоичного вывода. В таком случае попробуйте вместо этого использовать popen() .
Список параметров
Команда, которая будет выполнена.
Возвращаемые значения
Строка ( string ), содержащая вывод выполненной команды, false , если канал не может быть установлен или null в случае возникновения ошибки или отсутствии вывода команды.
Эта функция может вернуть null в двух случаях: если произошла ошибка или если выполняемая команда ничего не выводит. Не пользуйтесь этой функцией, для определения, успешно ли выполнилась команда. Вместо этого используйте exec() , так как она предоставляет возможность проверить код возврата.
Ошибки
Выдаётся ошибка уровня E_WARNING , когда канал не может быть установлен.
Примеры
Пример #1 Пример использования shell_exec()
Смотрите также
- exec() — Выполнить внешнюю программу
- escapeshellcmd() — Экранировать метасимволы командной строки
User Contributed Notes 33 notes
If you’re trying to run a command such as «gunzip -t» in shell_exec and getting an empty result, you might need to add 2>&1 to the end of the command, eg:
Won’t always work:
echo shell_exec(«gunzip -c -t $path_to_backup_file»);
Should work:
echo shell_exec(«gunzip -c -t $path_to_backup_file 2>&1»);
In the above example, a line break at the beginning of the gunzip output seemed to prevent shell_exec printing anything else. Hope this saves someone else an hour or two.
To run a command in background, the output must be redirected to /dev/null. This is written in exec() manual page. There are cases where you need the output to be logged somewhere else though. Redirecting the output to a file like this didn’t work for me:
# this doesn’t work!
shell_exec ( «my_script.sh 2>&1 >> /tmp/mylog &» );
?>
Using the above command still hangs web browser request.
Seems like you have to add exactly «/dev/null» to the command line. For instance, this worked:
# works, but output is lost
shell_exec ( «my_script.sh 2>/dev/null >/dev/null &» );
?>
But I wanted the output, so I used this:
proc_open is probably a better solution for most use cases as of PHP 7.4. There is better control and platform independence. If you still want to use shell_exec(), I like to wrap it with a function that allows better control.
Something like below solves some problems with background process issues on apache/php. It also
public function sh_exec(string $cmd, string $outputfile = «», string $pidfile = «», bool $mergestderror = true, bool $bg = false) <
$fullcmd = $cmd;
if(strlen($outputfile) > 0) $fullcmd .= » >> » . $outputfile;
if($mergestderror) $fullcmd .= » 2>&1″;
if($bg) <
$fullcmd = «nohup » . $fullcmd . » &»;
if(strlen($pidfile)) $fullcmd .= » echo $! > » . $pidfile;
> else <
if(strlen($pidfile) > 0) $fullcmd .= «; echo $$ > » . $pidfile;
>
shell_exec($fullcmd);
>
A simple way to handle the problem of capturing stderr output when using shell-exec under windows is to call ob_start() before the command and ob_end_clean() afterwards, like this:
()
$dir = shell_exec ( ‘dir B:’ );
if is_null ( $dir )
< // B: does not exist
// do whatever you want with the stderr output here
>
else
< // B: exists and $dir holds the directory listing
// do whatever you want with it here
>
ob_end_clean (); // get rid of the evidence 🙂
?>
If B: does not exist then $dir will be Null and the output buffer will have captured the message:
‘The system cannot find the path specified’.
(under WinXP, at least). If B: exists then $dir will contain the directory listing and we probably don’t care about the output buffer. In any case it needs to be deleted before proceeding.
I’m not sure what shell you are going to get with this function, but you can find out like this:
= ‘set’ ;
echo «» ;
?>
On my FreeBSD 6.1 box I get this:
USER=root
LD_LIBRARY_PATH=/usr/local/lib/apache2:
HOME=/root
PS1=’$ ‘
OPTIND=1
PS2=’> ‘
LOGNAME=root
PPID=88057
PATH=/etc:/bin:/sbin:/usr/bin:/usr/sbin
SHELL=/bin/sh
IFS=’
‘
Very interesting. Note that the PATH may not be as complete as you need. I wanted to run Ghostscript via ImageMagik’s «convert» and ended up having to add my path before running the command:
= ‘export PATH=»/usr/local/bin/»; convert -scale 25%x25% file1.pdf[0] file2.png 2>&1’ ;
echo «» ;
?>
ALSO, note that shell_exec() does not grab STDERR, so use «2>&1» to redirect it to STDOUT and catch it.
I had trouble with accented caracters and shell_exec.
Executing this command from shell :
/usr/bin/smbclient ‘//BREZEME/peyremor’ -c ‘dir’ -U ‘peyremor%*********’ -d 0 -W ‘ADMINISTRATIF’ -O ‘TCP_NODELAY IPTOS_LOWDELAY SO_KEEPALIVE SO_RCVBUF=8192 SO_SNDBUF=8192’ -b 1200 -N 2>&1
Vidéos D 0 Tue Jun 12 14:41:21 2007
Desktop DH 0 Mon Jun 18 17:41:36 2007
Using php like that :
shell_exec(«/usr/bin/smbclient ‘//BREZEME/peyremor’ -c ‘dir’ -U ‘peyremor%*******’ -d 0 -W ‘ADMINISTRATIF’ -O ‘TCP_NODELAY IPTOS_LOWDELAY SO_KEEPALIVE SO_RCVBUF=8192 SO_SNDBUF=8192’ -b 1200 -N 2>&1»)
Vid Desktop DH 0 Mon Jun 18 17:41:36 2007
The two lines were concatenated from the place where the accent was.
I found the solution : php execute by default the command with LOCALE=C.
I just added the following lines before shell_exec and the problem was solved :
$locale = ‘fr_FR.UTF-8’;
setlocale(LC_ALL, $locale);
putenv(‘LC_ALL=’.$locale);
Just adapt it to your language locale.
Here is a easy way to grab STDERR and discard STDOUT:
add ‘2>&1 1> /dev/null’ to the end of your shell command
For example:
= shell_exec ( ‘ls file_not_exist 2>&1 1> /dev/null’ );
?>
Here is my gist to all:
function execCommand($command, $log) <
if (substr(php_uname(), 0, 7) == «Windows»)
<
//windows
pclose(popen(«start /B » . $command . » 1> $log 2>&1″, «r»));
>
else
<
//linux
shell_exec( $command . » 1> $log 2>&1″ );
>
On Windows, if shell_exec does NOT return the result you expected and the PC is on an enterprise network, set the Apache service (or wampapache) to run under your account instead of the ‘Local system account’. Your account must have admin privileges.
To change the account go to console services, right click on the Apache service, choose properties, and select the connection tab.
How to get the volume label of a drive on Windows
function GetVolumeLabel ( $drive ) <
// Try to grab the volume name
if ( preg_match ( ‘#Volume in drive [a-zA-Z]* is (.*)\n#i’ , shell_exec ( ‘dir ‘ . $drive . ‘:’ ), $m )) <
$volname = ‘ (‘ . $m [ 1 ]. ‘)’ ;
> else <
$volname = » ;
>
return $volname ;
>
print GetVolumeLabel ( «c» );
?>
Note: The regular expression assumes a english version of Windows is in use. modify it accordingly for a different localized copy of Windows.
I have PHP (CGI) and Apache. I also shell_exec() shell scripts which use PHP CLI. This combination destroys the string value returned from the call. I get binary garbage. Shell scripts that start with #!/usr/bin/bash return their output properly.
A solution is to force a clean environment. PHP CLI no longer had the CGI environment variables to choke on.
// Binary garbage.
$ExhibitA = shell_exec ( ‘/home/www/myscript’ );
// Perfect.
$ExhibitB = shell_exec ( ‘env -i /home/www/myscript’ );
?>
— start /home/www/myscript
#!/usr/local/bin/phpcli
echo( «Output.\n» );
Be careful as to how you elevate privileges to your php script. It’s a good idea to use caution and planing. It is easy to open up huge security holes. Here are a couple of helpful hints I’ve gathered from experimentation and Unix documentation.
Things to think about:
1. If you are running php as an Apache module in Unix then every system command you run is run as user apache. This just makes sense.. Unix won’t allow privileges to be elevated in this manner. If you need to run a system command with elevated privileges think through the problem carefully!
2. You are absolutely insane if you decide to run apache as root. You may as well kick yourself in the face. There is always a better way to do it.
3. If you decide to use a SUID it is best not to SUID a script. SUID is disabled for scripts on many flavors of Unix. SUID scripts open up security holes, so you don’t always want to go this route even if it is an option. Write a simple binary and elevate the privileges of the binary as a SUID. In my own opinion it is a horrible idea to pass a system command through a SUID— ie have the SUID accept the name of a command as a parameter. You may as well run Apache as root!
As others have noted, shell_exec and the backtick operator (`) both return NULL if the executed command doesn’t output anything.
This can be worked around by doing anything like the following:
Here we’re simply outputting blank whitespace if the command succeeds — which satisfies this slightly strange issue. From there, you can trim() the command output etc.
it took me a heck of a lot of head banging to finally solve this problem so I thought that I would mention it here.
If you are using Eclipse and you try to do something like
= shell_exec ( «php -s $File » ); //this fails
?>
it will always fail when run inside of the Eclipse debugger. This happens on both Linux and Windows. I finally isolated the problem to changes that Eclipse makes to the environment when debugging.
The fix is to force the ini setting. If you don’t need an ini then -n is sufficient.
= shell_exec ( «php -n -s $File » ); //this works
?>
Of course if you run it outside of the debugger then it works fine without the -n. You may want to use a debug flag to control this behavior.
shell_exec is extremely useful as a substitute for the virtual() function where unavailable (Microsoft IIS for example). All you have to do is remove the content type string sent in the header:
This works fine for me as a substitute for SSI or the virtual() func.
Источник