簡體   English   中英

從php或python調用時,Bash腳本會掛起

[英]Bash script hangs when called from php or python

我是bash的新手,我編寫了一個bash腳本,從頭到尾讀取一個大的syslog文件,查找屬於給定分鍾(最后一分鍾)之前的條目,然后計算每個條目的出現次數。給定的模式在那一刻。 如果從PHP / Python運行它不起作用,但如果我像這樣直接調用它,它可以工作:

sh /path/to/logparser.sh /path/to/big.log '2013-09-23T08:38' '2013-09-23T08:37' 'MySQL has gone away' 'Unhandled Error timed out'

以下是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'工作

但是,當我通過從PHP運行pasthru()或Python的通過subprocess.Popen().communicate()它掛起。 如果我用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命令的結果
  • 文件權限:PHP和Python都可以完美地運行更簡單的bash腳本,例如包含date liunx命令的文件; 日志文件具有所有的讀取權限
  • bad params:我在bash腳本中比較了PHP / Python發送的params和通過命令行發送的params,它們是相同的

我怎么能讓它從PHP / Python調用?

你的代碼似乎都沒有將你的日志文件傳遞給你的shell腳本,你的shell中沒有設置logfile變量,而是從stdin中輸入tac wait輸入。

就像你的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腳本的實際原因可能不同,但通常這是腳本掛起的基本原因。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM