PHP exec() multiple commands that are not separate to each other [duplicate] - php

I want to run two commands in a Windows CMD console.
In Linux I would do it like this
touch thisfile ; ls -lstrh
How is it done on Windows?

Like this on all Microsoft OSes since 2000, and still good today:
dir & echo foo
If you want the second command to execute only if the first exited successfully:
dir && echo foo
The single ampersand (&) syntax to execute multiple commands on one line goes back to Windows XP, Windows 2000, and some earlier NT versions. (4.0 at least, according to one commenter here.)
There are quite a few other points about this that you'll find scrolling down this page.
Historical data follows, for those who may find it educational.
Prior to that, the && syntax was only a feature of the shell replacement 4DOS before that feature was added to the Microsoft command interpreter.
In Windows 95, 98 and ME, you'd use the pipe character instead:
dir | echo foo
In MS-DOS 5.0 and later, through some earlier Windows and NT versions of the command interpreter, the (undocumented) command separator was character 20 (Ctrl+T) which I'll represent with ^T here.
dir ^T echo foo

A quote from the documentation:
Source: Microsoft, Windows XP Professional Product Documentation, Command shell overview
Also: An A-Z Index of Windows CMD commands
Using multiple commands and conditional processing symbols
You can run multiple commands from a single command line or script using conditional processing symbols. When you run multiple commands with conditional processing symbols, the commands to the right of the conditional processing symbol act based upon the results of the command to the left of the conditional processing symbol.
For example, you might want to run a command only if the previous command fails. Or, you might want to run a command only if the previous command is successful.
You can use the special characters listed in the following table to pass multiple commands.
& [...]
command1 & command2
Use to separate multiple commands on one command line. Cmd.exe runs the first command, and then the second command.
&& [...]
command1 && command2
Use to run the command following && only if the command preceding the symbol is successful. Cmd.exe runs the first command, and then runs the second command only if the first command completed successfully.
|| [...]
command1 || command2
Use to run the command following || only if the command preceding || fails. Cmd.exe runs the first command, and then runs the second command only if the first command did not complete successfully (receives an error code greater than zero).
( ) [...]
(command1 & command2)
Use to group or nest multiple commands.
; or ,
command1 parameter1;parameter2
Use to separate command parameters.

& is the Bash equivalent for ; ( run commands) and && is the Bash equivalent of && (run commands only when the previous has not caused an error).

If you want to create a cmd shortcut (for example on your desktop) add /k parameter (/k means keep, /c will close window):
cmd /k echo hello && cd c:\ && cd Windows

You can use & to run commands one after another. Example: c:\dir & vim myFile.txt

You can use call to overcome the problem of environment variables being evaluated too soon - e.g.
set A=Hello & call echo %A%

A number of processing symbols can be used when running several commands on the same line, and may lead to processing redirection in some cases, altering output in other case, or just fail. One important case is placing on the same line commands that manipulate variables.
#echo off
setlocal enabledelayedexpansion
set count=0
set "count=1" & echo %count% !count!
0 1
As you see in the above example, when commands using variables are placed on the same line, you must use delayed expansion to update your variable values. If your variable is indexed, use CALL command with %% modifiers to update its value on the same line:
set "i=5" & set "arg!i!=MyFile!i!" & call echo path!i!=%temp%\%%arg!i!%%
path5=C:\Users\UserName\AppData\Local\Temp\MyFile5

cmd /c ipconfig /all & Output.txt
This command execute command and open Output.txt file in a single command

So, I was trying to enable the specific task of running RegAsm (register assembly) from a context menu. The issue I had was that the result would flash up and go away before I could read it. So I tried piping to Pause, which does not work when the command fails (as mentioned here Pause command not working in .bat script and here Batch file command PAUSE does not work). So I tried cmd /k but that leaves the window open for more commands (I just want to read the result). So I added a pause followed by exit to the chain, resulting in the following:
cmd /k C:\Windows\Microsoft.NET\Framework\v4.0.30319\regasm.exe "%1" /codebase \"%1\" & pause & exit
This works like a charm -- RegAsm runs on the file and shows its results, then a "Press any key to continue..." prompt is shown, then the command prompt window closes when a key is pressed.
P.S. For others who might be interested, you can use the following .reg file entries to add a dllfile association to .dll files and then a RegAsm command extension to that (notice the escaped quotes and backslashes):
[HKEY_CLASSES_ROOT\.dll]
"Content Type"="application/x-msdownload"
#="dllfile"
[HKEY_CLASSES_ROOT\dllfile]
#="Application Extension"
[HKEY_CLASSES_ROOT\dllfile\Shell\RegAsm]
#="Register Assembly"
[HKEY_CLASSES_ROOT\dllfile\Shell\RegAsm\command]
#="cmd /k C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\regasm.exe \"%1\" /codebase \"%1\" & pause & exit"
Now I have a nice right-click menu to register an assembly.

In windows, I used all the above solutions &, && but nothing worked
Finally ';' symbol worked for me
npm install; npm start

Well, you have two options: Piping, or just &:
DIR /S & START FILE.TXT
Or,
tasklist | find "notepad.exe"
Piping (|) is more for taking the output of one command, and putting it into another. And (&) is just saying run this, and that.

In order to execute two commands at the same time, you must put an & (ampersand) symbol between the two commands. Like so:
color 0a & start chrome.exe
Cheers!

I try to have two pings in the same window, and it is a serial command on the same line. After finishing the first, run the second command.
The solution was to combine with start /b on a Windows 7 command prompt.
Start as usual, without /b, and launch in a separate window.
The command used to launch in the same line is:
start /b command1 parameters & command2 parameters
Any way, if you wish to parse the output, I don't recommend to use this.
I noticed the output is scrambled between the output of the commands.

Use & symbol in windows to use command in one line
C:\Users\Arshdeep Singh>cd Desktop\PROJECTS\PYTHON\programiz & jupyter notebook
like in linux
we use,
touch thisfile ; ls -lstrh

I was trying to create batch file to start elevated cmd and to make it run 2 separate commands.
When I used & or && characters, I got a problem. For instance, this is the text in my batch file:
powershell.exe -Command "Start-Process cmd \"/k echo hello && call cd C:\ \" -Verb RunAs"
I get parse error:
After several guesses I found out, that if you surround && with quotes like "&&" it works:
powershell.exe -Command "Start-Process cmd \"/k echo hello "&&" call cd C:\ \" -Verb RunAs"
And here's the result:
May be this'll help someone :)

No, cd / && tree && echo %time%. The time echoed is at when the first command is executed.
The piping has some issue, but it is not critical as long as people know how it works.

One more example: For example, when we use the gulp build system, instead of
gulp - default > build
gulp build - build build-folder
gulp watch - start file-watch
gulp dist - build dist-folder
We can do that with one line:
cd c:\xampp\htdocs\project & gulp & gulp watch

Yes there is. It's &.
&& will execute command 2 when command 1 is complete providing it didn't fail.
& will execute regardless.

With windows 10 you can also use scriptrunner:
ScriptRunner.exe -appvscript demoA.cmd arg1 arg2 -appvscriptrunnerparameters -wait -timeout=30 -rollbackonerror -appvscript demoB.ps1 arg3 arg4 -appvscriptrunnerparameters -wait -timeout=30 -rollbackonerror
it allows you to start few commands on one line you want you can run them consecutive or without waiting each other, you can put timeouts and rollback on error.

Try to create a .bat ot .cmd file with those lines using doskey key and $T which is equivalent to & to do several command line in just one line :
touch=echo off $T echo. ^> $* $T dir /B $T echo on
It'll create an empty file.
Example:
touch myfile
In cmd you'll get something like this:
But as mentioned previously by others, it is really advised to use & operator to do many command line in one line from CMD prompt.
Enjoy =)

When you try to use or manipulate variables in one line beware of their content! E.g. a variable like the following
PATH=C:\Program Files (x86)\somewhere;"C:\Company\Cool Tool";%USERPROFILE%\AppData\Local\Microsoft\WindowsApps;
may lead to a lot of unhand-able trouble if you use it as %PATH%
The closing parentheses terminate your group statement
The double quotes don't allow you to use %PATH% to handle the parentheses problem
And what will a referenced variable like %USERPROFILE% contain?

It's simple: just differentiate them with && signs.
Example:
echo "Hello World" && echo "GoodBye World".
"Goodbye World" will be printed after "Hello World".

Related

PHP command in Bash does not execute code

Ok, so I have a problem with this thing I found on a MacBook Air. It's called terminal and you can do crazy stuff on it. So anyways, when I enter the command "php" it gives me a multiline console but it doesn' do anything when I run a line of php! For instance, I type echo "Hello World" but it just returns it like a typewriter and nothing happens! Can someone please tell me what is going on, and is there a way to exit this?
Firstly check if you have php properly installed:
type in console:
php -v
you should see version of installed php for ex.:
PHP 7.3.3 ...
to run single line of code from console you do it this way:
php -r 'echo "\nHello World\n";'
where \n is new line character.
to enter interactive mode and run multiple lines of code:
php -a
and once you see:
Interactive mode enabled
php >
type:
echo "\nHello World\n";
and hit [Enter] key.
that's it.
to leave interactive mode type:
exit
note lack of ; at the end.
If you want to run from console a php code that you have in a file:
php -f <path-to-the-file>
but this is a default behavior of php so if you miss flag -f and just type:
php
it will do nothing, expecting you providing it a path to file after the php like in the example with flag -f:
php <path-to-file>
So if a programmer intention is to enter an interactive mode but he types only php without any flags, the php will not warn about missing path to the file so programmer may have the impression he's into php interactive mode as he wanted but this is not true.
to see all possible options in php cli, type:
php --help
I believe if you just type php into the terminal it will start a php server process on the local mac. If you want to run a script you have to cd in to to the working directory and type php filename.php.
If you want to use PHP code directly you must enter php -a without a flag you will just enter in php environment.
When running the php command directly from your command line, it behaves as it is reading a .php from the command line
You noticed that it just echo's back any thing you write toward it, this is the same as it is executing a .php file, its echoĆ­ng any html back to the browser
Example:
$ php
sss
<?PHP
echo 'Hello!';
?>
More data!
ctrl + d (to signal that the end of the filehas reached)
Output:
sss
Hello!More data!

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"...

PHP exec(psexec.exe) hangs indefinitely

I have a development / testing setup on a windows box and need to test calling a background process. I am using http://www.somacon.com/p395.php as a list of options for running a background service.
Here is the sample code I am trying to run:
$string = "PsExec.exe -d cmd /c \"mspaint\"";
echo $string;
exec($string, $data);
This works when I type it into the command line.
I haven't attempted to do a lot of exec's on Windows, but it would be nice to be able to test it locally before moving to a Linux box.
Right now, I am thinking it has something to do with the fact that psexec opens a new window? I don't know how to fix that, however.
There are no apache or PHP error logs being generated, the page just never stops. This also seems to override PHP's max execution time.
EDIT:
This is not fully correct answer. The command psexec \\machine cmd.exe /C 1 & dir won't hang because psexec first return saying that command 1 doesn't exists in remote machine and then dir is evaluated in the local machine. I got tricked by cmd operator order. The & operator is being invoked in the local cmd.exe process, not the remote one. But the logic still applies if you quote the command: psexec \\machine cmd.exe /C "1 & dir".
Original Answer:
There is something strange going on while invoking psexec within PHP in windows. No matter if you are using shell_exec(), exec(), popen() or proc_open(). It will hang anyway.
Honestly I don't know what's going on, you could also download PsExplorer in order to trace your process command line, arguments, etc. You'll find this tool very useful.
I'm using XAMPP on Windows, and after certain tests I found this:
First of all create a test file (i.e. test.php) and place it in your web server so you can access it with this content:
<?php
echo "<pre>".shell_exec("psexec \\\\machine <options> cmd.exe /C dir")."</pre>";
?>
Note that you could use GET arguments in order to create a more flexible example. To debunk that this indeed is working before you test over a webpage, issue the command php <path-to-the-file>\test.php. That will work perfectly. But, it won't work on a web browser.
If you kill the process, you'll get the first line: El volumen de la unidad C no tiene etiqueta.. Next line, in my language there's an accent included so I thought It could be encoding (or code pages) issues. So instead of cmd.exe /C dir I tested cmd.exe /C chcp 850 && dir. That, for my surprise, works.
Then, I realize that no matter what command you set before it will also work, for instance, cmd.exe /C 123 & dir (note the single & as I'm not evaluating the command output).
Honestly, I don't know what is going on with psexec and PHP via web browser. More surprisingly, commands like cmd.exe /C copy cmd.exe cmd.exe.deleteme and cmd.exe /C mkdir deletethis will work!
So, you could give it a try to cmd.exe /C 1 & \"mspaint\" as your problem and my seems similars. For single commands could be a workaround but I'm developing an unattended framework for installing software and all my files are .cmd or .exe or .bat files.
Let me know If you found something interesting :)
I have a solution!
This topic is old but still relevant. I wanted to use PsExec 2.2 with PHP 7.2.0 RC3 to execute a script remotely. I need the output of the script and so i was using PsExec.exe -accepteula \\HOST -u xxx -p xxx with >> LOGFILE 2>&1.
Because I dont want to wait the script to finish, I used exec() like this: exec('start /p cmd /c PsExec.exe -accepteula \\HOST -u xxx -p xxx >> LOGFILE 2>&1').
My php script continues working and PsExec does his job too.
Everything works fine but my LOGFILE always contains only the first line of the STDOUT output.
I have tried many solutions mentioned here, but none of them worked for me. Executing the command in the CMD directly, PsExec returns all lines of STDOUT but inside php it does not.
At the php doc for exec() I have found comments where some people used PsExec to run a programm without waiting (http://php.net/manual/de/function.exec.php#86438). As a last chance I tried the following: exec('PsExec.exe -accepteula -i -d cmd /c PsExec.exe -accepteula \\HOST -u xxx -p xxx >> LOGFILE 2>&1')... And it works!
PsExec now returns everthing into my LOGFILE. I hope I could help you and save you some time.
My current solution was to use WScript.Shell:
$string = "cmd /c \"cd {$full_base}{$newSource} && ant release > compile.txt\"";
$Shell = new COM("WScript.Shell");
$exec = $Shell->Run($string, 0, false);
Not sure if this was definitively answered or not, but I was having the same problem with PSEXEC hanging, though in my case, on some machines it did, and others it didn't. It turned out to be accepting the EULA. On machines that I'd run it from a command line and used the same username/password as my PHP script, it ran without hanging.
Further research showed that I could specify the EULA acceptance by including it in the command being executed from PHP:
This DID hang: psexec \\MACHINENAME ...
This did NOT: psexec /accepteula \\MACHINENAME ...
ok here are the things. I also jumped into similar condition as you were and hopefully since i am commenting this late you must have figured out a way too .But for those who are still in this problem , i suggest them few tips .
1)The code that has been posted is super fine , no problem with that thing. If your page hangs out infinitely then try to add -i -d params before the source exe. (see the documentation HERE ). You can also add -accepteula (EULA) flag in the command to let the page load and not to wait for that command to finish(solves the infinite wait problem).
2)For me these things didnt work . It doesnt mean that you guys dont try these things .these are the first steps if your code starts working then thats fine for you.Else ,make another account as an adminstrative one ,type services.msc in the start menu , you will see the page there. Search for wampapache or xammp services ,excluding mysqld one. Then simply click on that service .GO to log on tab ,select This account .Select the previously made admin acc , type its password if you set that else leave the textbox empty.Type the name of that account as \\accname at the name field . If u dont know the account name ,Click to Browse->Advanced->FInd now you will see that name account . Select, apply settings and restart the wamp app and you are good to go :)
Also make sure to double check the string you feed into your exec command. Seems trivial, but had me stumped for awhile. In many cases PHP escapes the double backslash in your machine address which throws everything off. To get around this, create your string like:
$string = 'PSExec /accepteula \\\\MACHINENAME ...'

execute two shell commands in single exec php statement

I want to display all the files that are modified after a specified date
the commands are
touch --date '2011-09-19 /home/ , find /home/
How i can execute this two commands in single exec statement.Thanks in advance
You can use either a ; or a && to separate the comands. The ; runs both commands unconditionally. If the first one fails, the second one still runs. Using && makes the second command depend on the first. If the first command fails, the second will NOT run.
command1 ; command2 (run both uncondtionally)
command1 && command2 (run command2 only if command1 succeeds)
This is how I did it simultaneously encode thumbs, and then flv video..I need to generate 2 thumbs from avi file. After the thumbs I need to convert the same avi to flv or whatever. So, here is the code I normally used.
$command_one = "do whatever the script does best";
$command_two = "do whatever the script does second best";
//execute and redirect standard stream ..
#exec($command_one."&& ".$command_two.">/dev/null 1>/dev/null 2>/dev/null &");
You can also run array of commands with exec, if you want :)
foreach($crapatoids as $crap){
$command_name = $crap;
//exec the crap below
#exec ($command_name." >/dev/null 1>/dev/null 2>/dev/null &");
}
Seperate them with a semicolon (;). Example:
exec("touch --date '2011-09-19' /home/; find /home/");
The semicolon separator allows you to run multiple commands on one line.
<?php
$output = shell_exec("touch --date '2011-09-19' /home/; find /home/");
echo "<pre>" . $output . "</pre>";
?>
Actually, my problem came from execution python file in a virtual environment of Python. Generally, Python website instructs us to go through command lines: create a virtual env --> activate it --> call Python file (e.g: python3 yourPyFile.py). However, when I was trying to adapt these steps through calling in php with exec() method, it didn't work. Finally, I found out you don't need to activate env at all, what you only need to use a python which already generated when you creating virtual env by path/to/virtual/env/bin/python3 yourPyFile.py.

Bizarre php shell script behavior

It may help if you are on a Mac and use TextMate, though not entirely necessary.
My php location:
$which php
/opt/local/bin/php
The script:
#!/opt/local/bin/php
<?php
shell_exec("echo -n 'my-string' > out.txt");
?>
The -n to echo suppress the newline that is automatically added to all shell echo commands.
If I run the above php code from the shell:
chmod u+x myfile.php
./myfile.php
I end up with 'out.txt', the contents of which being:
-n my-string
If I run the exact same code within TextMate, the contents of 'out.txt' will be correct:
my-string
I can't figures out what php is up to with putting the literal string '-n' in the output. I really wonder why TextMate does the correct thing. I have checked that both are using the same php, php -i shows mostly the same stuff, of course there are differences as one is run within TextMate, the other in the shell, so one output has pointers to the file whereas the other doesn't. As far as I can tell, $PATH and $ENV are the same.
I have tried a handful of different methods to work around this none of which are working. I actually will not be able to use a workaround, as this has been distilled down to a simple case for posting to SO. My use case for this pipes to pbcopy, which I believed was a Mac OS X only feature, so I used >> redirection here because that is universal.
Ultimately, I want a result on my clipboard that does not have a trailing newline, which is dangerous as pasting that in a shell will execute whatever preceded it.
Thanks
Is it possible that php is calling a different echo than your shell built in echo? Many versions of echo do not support -n and will output it as part of your string.
You could try shell_exec("which echo"); to find out which it is running.
Note that printf will not display the new line unless you explicitly add it. So you can use which printf to figure out where this resides and call it instead.
shell_exec("/usr/local/bin/printf '%s' 'mystring' > out.txt");
PHP just defers the call to popen in Unix platforms. See the manual page for Mac OS X:
The command argument is a pointer to a null-terminated string containing a shell command line. This
command is passed to /bin/sh, using the -c flag; interpretation, if any, is performed by the shell.
So it should be the same as running /bin/sh -c "echo -n 'my-string' > out.txt"

Categories