百科狗-知识改变命运!
--

exec() - 执行一个外部程序 - php 执行命令函数

梵高1年前 (2023-11-21)阅读数 13#技术干货
文章标签命令

exec()

(PHP 4, PHP 5, PHP 7)

执行一个外部程序

说明

exec(string $command[,array &$output[,int &$return_var]]): string

exec()执行$command参数所指定的命令。

参数

$command

要执行的命令。

$output

如果提供了$output参数,那么会用命令执行的输出填充此数组,每行输出填充数组中的一个元素。数组中的数据不包含行尾的空白字符,例如n字符。请注意,如果数组中已经包含了部分元素,exec()函数会在数组末尾追加内容。如果你不想在数组末尾进行追加,请在传入exec()函数之前对数组使用unset()函数进行重置。

$return_var

如果同时提供$output和$return_var参数,命令执行后的返回状态会被写入到此变量。

返回值

命令执行结果的最后一行内容。如果你需要获取未经处理的全部输出数据,请使用passthru()函数。

如果想要获取命令的输出内容,请确保使用$output参数。

范例

Example #1exec()例程

注释

Warning

当用户提供的数据传入此函数,使用escapeshellarg()或escapeshellcmd()来确保用户欺骗系统从而执行任意命令。

Note:

如何程序使用此函数启动,为了能保持在后台运行,此程序必须将输出重定向到文件或其它输出流。否则会导致PHP 挂起,直至程序执行结束。Note:

On Windowsexec()will first start cmd.exe to launch the command. If you want to start an external program without starting cmd.exeuseproc_open()with the$bypass_shelloption set.

exec() - 执行一个外部程序 - php 执行命令函数

Note:安全模式启用时,可仅可用safe_mode_exec_dir执行文件。实际上,现在不允许在到可执行的路径中存在..组件。

Warning

安全模式启用时,命令字符串会被escapeshellcmd()转换。因此,echo y | echo x会变成echo y | echo x

参见

  • system() 执行外部程序,并且显示输出
  • passthru() 执行外部程序并且显示原始输出
  • escapeshellcmd()shell 元字符转义
  • pcntl_exec() 在当前进程空间执行指定程序
  • 执行运算符
This will execute $cmd in the background (no cmd window) without PHP waiting for it to finish, on both Windows and Unix. 
(This is for linux users only).
We know now how we can fork a process in linux with the & operator.
And by using command: nohup MY_COMMAND > /dev/null 2>&1 & echo $! we can return the pid of the process.
This small class is made so you can keep in track of your created processes ( meaning start/stop/status ).
You may use it to start a process or join an exisiting PID process. 
Can’t get the output from your exec’d command to appear in the $output array?
Is it echo’ing all over your shell instead?
Append "2>&1" to the end of your command, for example:
exec("xmllint --noout ~/desktop/test.xml 2>&1", $retArr, $retVal);
Will fill the array $retArr with the expected output; one line per array key.
I too wrestled with getting a program to run in the background in Windows while the script continues to execute. This method unlike the other solutions allows you to start any program minimized, maximized, or with no window at all. llbra@phpbrasil's solution does work but it sometimes produces an unwanted window on the desktop when you really want the task to run hidden.
start Notepad.exe minimized in the background:

start a shell command invisible in the background:

start MSPaint maximized and wait for you to close it before continuing the script:

For more info on the Run() method go to:
http://msdn.microsoft.com/library/en-us/script56/html/wsMthRun.asp
exec strips trailing whitespace off the output of a command. This makes it impossible to capture signifigant whitespace. For example, suppose that a program outputs columns of tab-delimited text, and the last column contains empty fields on some lines. The trailing tabs are important, but get thrown away.
If you need to preserve trialing whitespace, you must use popen() instead.
I tried to execute a command in background under Windows.
After struggling for hours with all these half ready examples I would like to share the syntax I found working (for windows at least). This is not tested under Linux as there are more elegant ways to spawn a process.
Based on the function from Arno van den Brink.

This works perfectly with e.g.

but the following does NOT work:

Why?
When windows sees quotation marks (\") it thinks this is the window title, not the command.
So, when your command needs quotation marks you HAVE TO provide a window name first, like
execInBackground("\"title\"" "\"c:\path with spaces\my program.exe\") 
Quotation marks are mandatiory for window title. Otherwise windows thinks this is the program name.
Weired, but "Hey! it's Windows!" :)
If you're trying to use exec in a script that uses signal SIGCHLD, (i.e. pcntl_signal(SIGCHLD,'sigHandler');) it will return -1 as the exit code of the command (although output is correct!). To resolve this remove the signal handler and add it again after exec. Code will be something like this:
...
pcntl_signal(SIGCHLD, 'sigHandler');
...
...
(more codes, functions, classes, etc)
...
...
// Now executing the command via exec
// Clear the signal
pcntl_signal(SIGCHLD, SIG_DFL);
// Execute the command
exec('mycommand',$output,$retval);
// Set the signal back to our handler
pcntl_signal(SIGCHLD, 'sigHandler');
// At this point we have correct value of $retval.
Same solution can apply to system and passthru as well.
Took quite some time to figure out the line I am going to post next. If you want to execute a command in the background without having the script waiting for the result, you can do the following:

There are a few thing that are important here. 
First of all: put the full path to the php binary, because this command will run under the apache user, and you will probably not have command alias like php set in that user.
Seccond: Note 2 things at the end of the command string: the '2>&1' and the '&'. The '2>&1' is for redirecting errors to the standard IO. And the most important thing is the '&' at the end of the command string, which tells the terminal not to wait for a response.
Third: Make sure you have 777 permissions on the 'log_file.log' file
Enojy!
In Windows, exec() issues an internal call to "cmd /c your_command". This implies that your command must follow the rules imposed by cmd.exe which includes an extra set of quotes around the full command:
- http://ss64.com/nt/cmd.html
Current PHP versions take this into account and add the quotes automatically, but old versions didn't.
Apparently, the change was made in PHP/5.3.0 yet not backported to 5.2.x because it's a backwards incompatible change. To sum up:
- In PHP/5.2 and older you have to surround the full command plus arguments in double quotes
- In PHP/5.3 and greater you don't have to (if you do, your script will break)
If you are interested in the internals, this is the source code:
sprintf(cmd, "%s /c \"%s\"", TWG(comspec), command); 
It can be found at http://svn.php.net/viewvc/ (please find php/php-src/trunk/TSRM/tsrm_win32.c, the comment system doesn't allow the direct link).
From what I've gathered asking around, there is no way to pass back a perl array into a php script using the exec function. 
The suggestion is to just print out your perl array variables at the end of your script, and then grabbing each array member from the array returned by the exec function. If you will be passing multiple arrays, or if you need to keep track of array keys as well as values, then as you print each array or hash variable at the end of your perl script, you should concatenate the value with the key and array name, using an underscore, as in:
 
foreach (@array) print "(array name)_(member_key)_($_)" ;
Then you would simply iterate through the array returned by the exec function, and split each variable along the underscore.
Here I like to especially thank Marat for the knowledge. Hope this is useful to others in search for similar answer!
I was trying to get an acceslist from a remote computer by executing cacls and parse it in php, all in a Windows environment with Apache. First i discovered psexec.exe from Windows SysInternals.
But with the following line, I didn´t get anything, it get hunged, although from the command line it worked nice:

To make it work I just followed the next steps:
- execute services.msc and find the apache service (In my case wampapache)
- Right button>Log On tab and change from Local System Account to a user created account, enter the username and the password and restart the service.
(I added this user to the administrators group to avoid permissions problems but its not recommended...)
It worked! And it may work with IIS too so try it if you have the same poblem....
Hope this helps someone, and sorry for my english
On Windows-Apache-PHP servers there is a problem with using the exec command more than once at the same time. If a script (with the exec command) is loaded more than once by the same user at the same time the server will freeze.
In my case the PHP script using the exec command was used as the source of an image tag. More than one image in one HTML made the server stop.
The problem is described here (http://bugs.php.net/bug.php?id=44942) toghether with a solution - stop the session before the exec command and start it again after it. 
[NOTE BY danbrown AT php DOT net: The following is a Linux script that the contributor of this note suggests be placed in a file named 'pstools.inc.php' to execute a process, check if a process exists, and kill a process by ID. Inspired by the Windows version at http://php.net/exec#59428 ] 
If SAFE_MODE is on, and you are trying to run a script in the background by appending "> /dev/null 2> /dev/null & echo $!" to the command line, the browser will hang until the script is done. 
My solution:
Create a shell script (ex. runscript.sh) which contains the execution line for the script you are trying to run in the background. 
The runscript.sh is run by an exec() call without the redirect string, which is now placed in the runscript.sh. 
runscript.sh will return almost immediately because output of the original script is redirected, and so will not hang your browser and the script runs fine in the background.
This is the second time this one got me, I thought someone else might find this note useful too.
I am creating a long running exec'd process that I can access with page submissions up to 2 hours later. The problem is this, the first time I access the page everything works like it should. The second time the web browser waits and waits and never gets any messages -- the CPU time is not affected so it is apparent that something is blocked.
What is actually happening is that all of the open files are being copied to the exec'd process -- including the network connections. So the second time I try to access the web page, I am being given the old http network connection which is now being ignored.
The solution is to scan all file handles from 3 on up and close them all. Remember that handles 0, 1, and 2 are standard input, standard output, and standard error.

鹏仔微信 15129739599 鹏仔QQ344225443 鹏仔前端 pjxi.com 共享博客 sharedbk.com

免责声明:我们致力于保护作者版权,注重分享,当前被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理!邮箱:344225443@qq.com)

图片声明:本站部分配图来自网络。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

内容声明:本文中引用的各种信息及资料(包括但不限于文字、数据、图表及超链接等)均来源于该信息及资料的相关主体(包括但不限于公司、媒体、协会等机构)的官方网站或公开发表的信息。部分内容参考包括:(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供参考使用,不准确地方联系删除处理!本站为非盈利性质站点,本着为中国教育事业出一份力,发布内容不收取任何费用也不接任何广告!)