PHP Command in script has different results than shell - php

I have the following lines in a BASH script:
ACTIONS_COMMAND="php -f $BASEDIR/scripts/activities.php < \"$SRC_DIR/%s/AndroidManifest.xml\""
printf -v ACTIONS_CMD "$ACTIONS_COMMAND" $FOLDER
$ACTIONS_CMD
This runs inside a loop to do the same operation to several Android applications.
When I echo the $ACTIONS_CMD and copy and paste the command, it produces the correct output, but the script itself starts PHP, but does not copy the STDIN. I know this because PHP hangs until I push Ctrl-D on the keyboard and then it complains there was no input.
I tried switching the PHP command to
ACTIONS_COMMAND="cat \"$SRC_DIR/%s/AndroidManifest.xml\" | php -f $BASEDIR/scripts/activities.php"
When the first file name is in quotes (which I think it should be for safety), I get
cat: "apps/app_name/AndroidManifest.xml": No such file or directory
cat: |: No such file or directory
cat: php: No such file or directory
cat: -f: No such file or directory
<?php
... REST OF PHP SCRIPT ...
and without the quotes, it just outputs to the terminal window.
If it matters, it is GNU bash, version 3.2.51(1)-release (x86_64-apple-darwin13).

You cannot execute programs with input/output redirection in a string like that. It will attempt to use the pipe and angle characters and the file as input to the program you executed.
You need to pass that string to a shell in order to do the redirection.
One way to do that is:
bash -c "$ACTIONS_COMMAND"

Related

Executing Scripts via PHP

I am trying to execute a script file (Batch or Python) in PHP (local WAMP server) that will open a program on my computer and send a keyboard shortcut to put the the program in fullscreen mode. I have this script already made using AutoHotKey (.ahk scripts).
I tried using these PHP commands to open a Batch file that runs the .ahk script:
system("cmd /c C:\wamp64\www\test.bat");
exec("test.bat");
exec("cmd.exe /c test.bat");
But all of these seem to just run the script on the webserver and not on my Windows computer so the .ahk file is never executed. I also tried directly executing .ahk file but I couldn't get that working either.
Does anyone know of a way I can use PHP(or another web language) to execute this script on my computer?
You have to specify absolute path for the batch file, as the CLI SAPI has nothing to do with WAMP's document root.
You have tried to pass full path in the first command. But the sequence \t within double quotes is parsed as a tabulation character. Change double quotes to single quotes:
system('cmd /c C:\wamp64\www\test.bat');
Also, I don't think you need to run cmd explicitly, since batch files are executable on Windows.

Use php exec to launch a linux command with brace expansion

How can I force the php exec() to interpret the linux brace expansion?
I am encountering a strange behavior, and did not find a way to fix it the way I want.
I want to execute a linux command containing brace expression to select a batch of files,
from php
I am using php to generate a "random" number of files, and want then to execute a shell script which will make something with the files.
Here is my bash version:
"$ echo $BASH_VERSION"
4.1.5(1)-release
To give a simple example, let's assume I create the following files:
touch /tmp/file_{1..12}.xml
shell.sh
#!/bin/sh
FILES=$*
echo "\n\nFILES: $FILES"
for f in $FILES; do
echo Posting file $f
done
test.php
<?php
$cmd = "./shell.sh /tmp/file_{1..12}.xml";
echo"\n\nCOMMAND:\n".$cmd."\n\n";
var_dump(shell_exec($cmd));
The output of "php test.php" is:
COMMAND:
./shell.sh /tmp/file_{1..12}.xml
string(66) "
FILES: /tmp/file_{1..12}.xml
Posting file /tmp/file_{1..12}.xml
"
I expect to have the same as if I run "./shell.sh /tmp/file_{1..12}.xml" from linux terminal:
$ ./shell.sh /tmp/file_{1..12}.xml
FILES: /tmp/file_1.xml /tmp/file_2.xml /tmp/file_3.xml /tmp/file_4.xml /tmp/file_5.xml /tmp/file_6.xml /tmp/file_7.xml /tmp/file_8.xml /tmp/file_9.xml /tmp/file_10.xml /tmp/file_11.xml /tmp/file_12.xml
Posting file /tmp/file_1.xml
Posting file /tmp/file_2.xml
Posting file /tmp/file_3.xml
Posting file /tmp/file_4.xml
Posting file /tmp/file_5.xml
Posting file /tmp/file_6.xml
Posting file /tmp/file_7.xml
Posting file /tmp/file_8.xml
Posting file /tmp/file_9.xml
Posting file /tmp/file_10.xml
Posting file /tmp/file_11.xml
Posting file /tmp/file_12.xml
But I also tried with or without escapeshellcmd()
with exec($cmd) AND other functions like system() or eval()...
None of them did the job...
I know that I could do the foreach loop in php, but I am sure there is a way to have this command interpreted as if it was launched from command line.
As #Josh Trii Johnston has pointed out, the 'outer' shell you are implicitly using to call your shell script using shell_exec() is probably not Bash in your case. This way, brace expansion never takes place because there is no shell capable of expanding the expression before calling your program (as it would be in an interactive Bash session).
You could
try to change the shell invoked by PHP's shell_exec(), but this may not be possible
call /bin/bash with your program and the brace expression instead of only the brace expression: $cmd = "/bin/bash -c './shell.sh /tmp/file_{1..12}.xml'";
use eval on the argument inside your script to expand the brace expression.
From the bash(1) man page:
If bash is invoked with the name sh, it tries to mimic the startup behavior of historical versions of sh as closely as possible, while conforming to the POSIX standard as well. [...] When invoked as sh, bash enters posix mode after the startup files are read.
Try changing
#!/bin/sh
to
#!/bin/bash
if you expect Bash behavior (there is no brace expansion in POSIX).
If all of the above does not help, you should make sure that brace expansion is activated by executing set -o (while calling your program from the PHP script). If it is off, you can turn it on using:
set -o braceexpand
I used your exact example on my OS X machine and it works as expected. What user are you executing php as? Is that user's shell (/bin/sh) set to a non-bash shell?
$ php test.php
COMMAND:
./shell.sh /tmp/file_{1..12}.xml
string(555) "\n\nFILES: /tmp/file_1.xml /tmp/file_2.xml /tmp/file_3.xml /tmp/file_4.xml /tmp/file_5.xml /tmp/file_6.xml /tmp/file_7.xml /tmp/file_8.xml /tmp/file_9.xml /tmp/file_10.xml /tmp/file_11.xml /tmp/file_12.xml\nPosting file /tmp/file_1.xml\nPosting file /tmp/file_2.xml\nPosting file /tmp/file_3.xml\nPosting file /tmp/file_4.xml\nPosting file /tmp/file_5.xml\nPosting file /tmp/file_6.xml\nPosting file /tmp/file_7.xml\nPosting file /tmp/file_8.xml\nPosting file /tmp/file_9.xml\nPosting file /tmp/file_10.xml\nPost"...

Piping PHP file content to PHP command in CLI

My question relate to the use of PHP in CLI. I don't know why the piping of the content of a PHP file to the PHP command works:
cat file.php | php
like in the installation of Composer Composer Installation:
curl -sS https://getcomposer.org/installer | php
If you don't give any argument to PHP, it reads from standard input (commonly called stdin).
If your output buffering is disabled, you can try to run php without argument, and type <?php echo "test\n"; + Enter, you'll see "test". stdin is basically the stream where your keyboard writes, and stdout is basically your terminal, where echo writes.
But the pipe ( | ) changes that behaviour : the standard output of the first program becomes the standard input of the second one.
This is a quite powerful thing our nix system shells offer :-).
As to "why it works": It works because the -cli variant of the PHP binary is designed to read from stdin and process input scripts from there alternatively.
The manpage lists various execution options. See the very last line:
PHP is a widely-used general-purpose scripting language that is espe‐
cially suited for Web development and can be embedded into HTML. This
is the command line interface that enables you to do the following:
You can parse and execute files by using parameter -f followed by the
name of the file to be executed.
Using parameter -r you can directly execute PHP code simply as you
would do inside a .php file when using the eval() function.
It is also possible to process the standard input line by line using
either the parameter -R or -F. In this mode each separate input line
causes the code specified by -R or the file specified by -F to be exe‐
cuted. You can access the input line by $argn. While processing the
input lines $argi contains the number of the actual line being pro‐
cessed. Further more the parameters -B and -E can be used to execute
code (see -r) before and after all input lines have been processed
respectively. Notice that the input is read from STDIN and therefore
reading from STDIN explicitly changes the next input line or skips
input lines.
If none of -r -f -B -R -F or -E is present but a single parameter
is given then this parameter is taken as the filename to parse and
execute (same as with -f). If no parameter is present then the
standard input is read and executed.
Normally you would not do it that way and would simply execute the file by php file.php. In this case, for whatever reason you want to do it that way, you need quotes around it with quotes
php -r "`cat file.php`"
Edit You could do this as well.
Put a hashbang at the front of the file like this
#!/usr/bin/env php
<?php
//code follows here
Then execute with
cat file.php | php

I need to run a python script from php

I have to design a interface using PHP for a software written in python. Currently this software is used from command line by passing input, mostly the input is a text file. There are series of steps and for every step a python script is called. Every step takes a text file as input and an generates an output text file in the folder decided by the user. I am using system() of php but I can't see the output but when I use the same command from command line it generates the output. Example of command :
python /software/qiime-1.4.0-release/bin/check_id_map.py -m /home/qiime/sample/Fasting_Map.txt -o /home/qiime/sample/mapping_output -v
try this
$script = 'software/qiime-1.4.0-release/bin/check_id_map.py -m /home/qiime/sample/Fasting_Map.txt -o /home/qiime/sample/mapping_output -v';
$a = exec($script);
If you are not on windows, have you tried adding 2>&1 (redirect stderr to stdout) to the end of the command?
$output = system("python /software/qiime-1.4.0-release/bin/check_id_map.py -m /home/qiime/sample/Fasting_Map.txt -o /home/qiime/sample/mapping_output -v 2>&1", $exitcode);
Found from http://www.php.net/manual/en/function.system.php#108713
Also the doc says that it
Returns the last line of the command output on success, and FALSE on
failure.
So if you are trying to get multiple lines, you may need to redirect it to a file and read that in.
instead of system() try surrounding the code in `ticks`...
It has a similar functionality but behaves a little differently in the way it returns the output..

Most correct way to run php at the linux shell

Is there a correct way to use php from the command line...or rather...is one way more correct than another ?
If you create a file, say test.php with the following code:
#!/usr/bin/php
<?php
print "This is a test".PHP_EOL;
print "This is another test!!";
?>
then chmod +x text.php (make it executable on linux).
You can then run in the following ways.....
./test.php
or
php test.php
I prefer just using ./test.php, but often see php test.php in examples.
ALSO
is the following correct syntax for the shebang line
#!/usr/bin/php
or is this more correct
#!/usr/bin/php -q
I've seen both, and see that the -q flag is to quiet the html stuff, but was wondering if
php compiled with cli compatibility really needs the -q flag ???
Thanks for your help :)
#!/usr/bin/php
On the first line of an interpreter script, the "#!", is the name of a program which should be used to interpret the contents of the file. For instance, if the first line contains
"#! /bin/sh"
, then the contents of the file are executed as a shell script.
In your case it means excute the script using the php file in /usr/bin location.
Using php test.php means that you are running your test.php with php so u don't need the first line. where as for ./test.php your file needs to be executable and first line is required.
And about the -q flag look at this
specifically on
rob 23-Mar-2007 11:48
There are better expanations if you see for -q. here's another one
If you are writing little php scripts for your own purposes, #! is fine.
If they are to be on some kind of world visible box (e.g. web server), then I'd say not so fine - since you have made them executable they are now a security risk.
I tend to use #! for perl, sh (which are always little private, non production things) and php somefile.php for PHP (which may or may not end up on a server).

Categories