我是 bash 的新手,我写了一个 bash 脚本,它从头到尾读取一个大的系统日志文件,查找属于给定分钟(最后一分钟的前一分钟)的条目,然后计算出现的次数每个给定的模式在那一分钟都有。 如果从 PHP/Python 运行它不起作用,但如果我像这样直接调用它它就起作用了:
sh/path/to/logparser.sh/path/to/big.log '2013-09-23T08:38' '2013-09-23T08:37' 'MySQL 已经消失' '未处理的错误超时'
logparser.sh
代码如下:
logfile=$1
echo $logfile
shift
minute=$1
echo $minute
shift
minute_before=$1
echo $minute_before
shift
command="tac $logfile | sed -n -e '/$minute/p' -e '/$minute_before/q'"
echo $command
if [ -f $logfile ]; then
buffer=$(eval $command)
echo "buffer complete"
exit 1
fi
旁注:
- 我使用了
buffer=$(eval $command)
因为buffer=$(tac $logfile | sed -n -e '/$minute/p' -e '/$minute_before/q')
即使在命令行中也会挂起 - 我在 sed 中使用了
-e '/$minute_before/q'
因为我无法让 `-e '/$minute/!q' 工作
但是当我通过 pasthru()
从 PHP 运行它或通过 subprocess.Popen().communicate()
从 Python 运行它时,它挂起。如果我使用 ps -ef r
检查进程,我会看到 tac
仍在运行。
这是调用 bash 脚本的 PHP 代码:
$env = $argv[1];
$service_name = $argv[2];
$logfile = $argv[3];
$minute = $argv[4];
$minute_before = $argv[5];
$command = 'sh '.dirname(__FILE__).'/logparser.sh ';
$n = count($argv);
for($i=3; $i<$n; $i++){
$command .= ' ' . escapeshellarg($argv[$i]);
}
$command .= "\n";
echo "\npassthru {$command}";
passthru($command, $out);
var_dump($out);
exit();
这是调用 bash 脚本的 Python 代码:
env = sys.argv[1]
service_name = sys.argv[2]
logfile = sys.argv[3]
minute = sys.argv[4]
minute_before = sys.argv[5]
args = ['sh', '%s/logparser.sh' % os.getcwd()]
for i in range(3, len(sys.argv)):
args.append(sys.argv[i])
print args
output = subprocess.Popen(args, stdout=subprocess.PIPE).communicate()
print output
我排除的其他内容:
- exec 权限:PHP 和 Python 都可以运行并获取
whoami
等 linux 命令的结果 - 文件权限:对于更简单的 bash 脚本,PHP 和 Python 都能完美运行,例如包含
date
liunx 命令的文件;日志文件对所有人具有读取权限 - 错误的参数:我在 bash 脚本中比较了 PHP/Python 发送的参数和通过命令行发送的参数,它们是相同的
我怎样才能让它从 PHP/Python 调用?
最佳答案
您的代码似乎都没有将您的日志文件传递给您的 shell 脚本,日志文件变量在您的 shell 中未设置,而是从 stdin 进行 tac 等待输入。
就像在您的 python 代码中一样,也许您需要这样做:
for i in range(1, len(sys.argv)):
args.append(sys.argv[i])
同样在您的 php 代码中:
$n = count($argv);
for($i=1; $i<$n; $i++){
$command .= ' ' . escapeshellarg($argv[$i]);
}
日志文件的路径未传递给您的 shell 脚本的实际原因可能有所不同,但通常这是脚本挂起的基本原因。
关于php - 从 php 或 python 调用时 Bash 脚本挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18956454/