使用php exec启动带有大括号扩展的linux命令

时间:2015-09-24 13:33:51

标签: php linux bash shell

如何强制php exec()解释linux括号扩展?

我遇到了一种奇怪的行为,并没有找到按照我想要的方式修复它的方法。

我想执行一个包含brace expression的linux命令来选择一批文件

来自php

我正在使用php生成"随机"文件数量,然后要执行一个shell脚本,它将使用这些文件。

这是我的bash版本:

  

" $ echo $ BASH_VERSION"

     

4.1.5(1) - 释放

举一个简单的例子,我们假设我创建了以下文件:

  

touch / tmp / file_ {1..12} .xml

shell.sh

X3270

test.php的

#!/bin/sh
FILES=$*
echo "\n\nFILES: $FILES"
for f in $FILES; do
  echo Posting file $f
done

" php test.php"的输出是:

<?php
$cmd = "./shell.sh /tmp/file_{1..12}.xml";
echo"\n\nCOMMAND:\n".$cmd."\n\n";
var_dump(shell_exec($cmd));

我希望和我一样运行&#34; ./ shell.sh /tmp/file_{1..12}.xml"来自linux终端:

  

$ ./shell.sh / tmp / file_ {1..12} .xml

     

文件:/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

     

发布文件/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

但我也尝试过或不使用escapeshellcmd() 使用exec($ cmd)和其他函数,如system()或eval()... 他们都没有完成这项工作......

我知道我可以在php中执行foreach循环,但我确信有一种方法可以将此命令解释为从命令行启动它。

2 个答案:

答案 0 :(得分:0)

  • 作为@Josh Trii Johnston has pointed out,您隐式用于使用shell_exec()调用shell脚本的'外部'shell可能不是Bash。这样,大括号扩展永远不会发生,因为在调用程序之前没有shell能够扩展表达式(就像在交互式Bash会话中一样)。

    你可以

    • 尝试更改PHP shell_exec()调用的shell,但may not be possible
    • 使用您的程序和大括号表达式而不是仅使用大括号表达式调用/bin/bash$cmd = "/bin/bash -c './shell.sh /tmp/file_{1..12}.xml'";
    • 在脚本内的参数上使用eval来扩展大括号表达式。
  • 来自bash(1)手册页:

      

    如果使用名称sh调用bash,它会尝试尽可能接近地模仿sh的历史版本的启动行为,同时也符合POSIX标准。 [...]当调用sh时,bash在读取启动文件后进入posix模式。

    尝试更改

    #!/bin/sh
    

    #!/bin/bash
    

    如果您期望Bash行为(POSIX中没有大括号扩展)。

  • 如果上述所有方法都没有帮助,您应该确保通过执行set -o(从PHP脚本调用程序时)激活大括号扩展。如果已关闭,您可以使用以下方式打开它:

    set -o braceexpand
    

答案 1 :(得分:0)

我在OS X机器上使用了您的确切示例,它按预期工作。你用什么用户执行php?该用户的shell(/bin/sh)是否设置为非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"...