我有一个PHP脚本,该脚本执行一个shell命令来查找给定两个文件之间的公用项。这是我的PHP脚本的开始:
$E7Bonded_File = "/opt/IBM/custom/NAC_Dslam/junk/PortParameter_E7_Bonded_cust_stats.csv";
$E7Single_File = "/opt/IBM/custom/NAC_Dslam/junk/PortParameter_E7_Single_cust_stats.csv";
$E7Common_File = "/opt/IBM/custom/NAC_Dslam/junk/Common_tn_SingleBonded_E7_cust_stats.csv";
//only do this once, with old single/bonded filenames. This will be a list to add to the existing Common file.
exec ("comm -12 <(cut -d ',' -f2 $E7Single_File| sort) <(cut -d ',' -f2 $E7Bonded_File| sort)", $outputCommon);
我在运行脚本时看到以下错误消息:
sh: -c: line 0: syntax error near unexpected token `('
sh: -c: line 0: `comm -12 <(cut -d ',' -f2 /opt/IBM/custom/NAC_Dslam/junk/PortParameter_E7_Single_cust_stats.csv| sort) <(cut -d ',' -f2 /opt/IBM/custom/NAC_Dslam/junk/PortParameter_E7_Bonded_cust_stats.csv| sort)'
我检查了一下,我的exec()
行的括号看起来还可以。
当我在命令行上运行shell命令时,它会返回一个如我期望的数字列表:
comm -12 <(cut -d ',' -f2 junk/PortParameter_E7_Single_cust_stats.csv| sort) <(cut -d ',' -f2 junk/PortParameter_E7_Bonded_cust_stats.csv| sort)
我在网上看了看,似乎在正确使用exec()
。我希望返回的数字存储为数组$outputCommon
。
关于此错误消息的任何想法吗?
*********更新答案***************
我的解决方案最终融合了马里奥和miken32 /我的同事
#!/bin/bash
,并且添加/bin/bash -c
如下:
exec(“ / bin / bash -c /opt/IBM/custom/NAC_Dslam/Common_list.sh”,$ outputShell);
将comm部分移至shell脚本后:
Common_list.sh:
#!/bin/bash
comm -12 <(cut -d ',' -f2 /opt/IBM/custom/NAC_Dslam/junk/PortParameter_E7_Single_cust_stats.csv| sort) <(cut -d ',' -f2 /opt/IBM/custom/NAC_Dslam/junk/PortParameter_E7_Bonded_cust_stats.csv| sort)
答案 0 :(得分:2)
最简单的解决方案可能是将其制成服务器上的可执行脚本:
#!/bin/bash
if [[ ! -r "$1" ]] || [[ ! -r "$2" ]]; then
printf "File not found\n" >&2
exit 1
fi
comm -12 <(cut -d ',' -f2 "$1"| sort) <(cut -d ',' -f2 "$2"| sort)
然后从PHP调用它:
$E7Bonded_File = escapeshellarg("/opt/IBM/custom/NAC_Dslam/junk/PortParameter_E7_Bonded_cust_stats.csv");
$E7Single_File = escapeshellarg("/opt/IBM/custom/NAC_Dslam/junk/PortParameter_E7_Single_cust_stats.csv");
//only do this once, with old single/bonded filenames. This will be a list to add to the existing Common file.
exec ("/usr/local/bin/your_script.sh $E7Single_File $E7Bonded_File", $outputCommon);
始终使用escapeshellarg()
转义您的shell参数,即使您认为它们很安全。
答案 1 :(得分:1)
此错误通常是针对不支持<()
表达式管道的非bash shell出现的。
在Ubuntu / Debian服务器上,默认/bin/sh
通常是dash
。
检查符号链接的二进制文件:
me@snip:~$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Jul 16 2017 /bin/sh -> dash
或者如@theotherguy所述,bash在以sh
开头时以受限壳运行。
请参阅$ _ENV [SHELL],以了解Apache / PHP默认使用的内容。更改环境变量。
要么对此进行调整,要么将shell_exec
cmdline换成/bin/bash -c '…'
。
答案 2 :(得分:0)
使用linter检查脚本时,它抱怨:
comm -12 <(cut -d ',' -f2 junk/PortParameter_E7_Single_cust_stats.csv| sort) <(cut -d ',' -f2 junk/PortParameter_E7_Bonded_cust_stats.csv| sort)
^-- SC2039: In POSIX sh, process substitution is undefined.
在我定义shebang #!/bin/sh
时发生这种情况,而#!/bin/bash
没有抱怨……因此答案可能是使用/usr/bin/bash
运行脚本。 escapeshellarg()
确实有用。
...
尝试shell_exec()
,只是因为exec()
不应调用任何shell。一个返回字符串输出,另一个可以返回数组。
或者,您可以使用exec()
显式调用bash:
exec('/bin/bash -c " command "', $stdOut);