【问题标题】:How to check the status of a shell script using subprocess module in Python?如何使用 Python 中的子进程模块检查 shell 脚本的状态?
【发布时间】:2013-12-27 03:45:07
【问题描述】:

我有一个简单的 Python 脚本,它将在 Python 中使用 subprocess mdoule 执行一个 shell 脚本。

下面是我的 Python shell 脚本,它调用testing.sh shell 脚本,它工作正常。

import os
import json
import subprocess

jsonData = '{"pp": [0,3,5,7,9], "sp": [1,2,4,6,8]}'
jj = json.loads(jsonData)

print jj['pp']
print jj['sp']

os.putenv( 'jj1',  'Hello World 1')
os.putenv( 'jj2',  'Hello World 2')
os.putenv( 'jj3', ' '.join( str(v) for v in jj['pp']  ) )
os.putenv( 'jj4', ' '.join( str(v) for v in jj['sp']  ) )

print "start"
subprocess.call(['./testing.sh'])
print "end"

下面是我的 shell 脚本 -

#!/bin/bash

for el1 in $jj3
do
    echo "$el1"
done

for el2 in $jj4
do
    echo "$el2"
done

for i in $( david ); do
    echo item: $i
done

现在我的问题是 -

如果你看到我的 Python 脚本,我正在打印 start,然后执行 shell 脚本,然后打印 end.. 所以假设我正在执行的 shell 脚本有任何问题,那么我不会想打印出end

所以在上面的例子中,shell 脚本将无法正常运行,因为david 不是 linux 命令,所以它会抛出错误。那么我应该如何查看整个 bash shell 脚本的状态,然后决定是否需要打印end

我刚刚添加了一个for循环示例,它可以是任何shell脚本..

可以吗?

【问题讨论】:

    标签: python bash shell subprocess


    【解决方案1】:

    只需使用call()的返回值即可:

    import subprocess
    
    rc = subprocess.call("true")
    assert rc == 0 # zero exit status means success
    rc = subprocess.call("false")
    assert rc != 0 # non-zero means failure
    

    如果命令失败,您可以使用check_call() 自动引发异常,而不是手动检查返回的代码:

    rc = subprocess.check_call("true") # <-- no exception
    assert rc == 0
    
    try:
        subprocess.check_call("false") # raises an exception
    except subprocess.CalledProcessError as e:
        assert e.returncode == 1
    else:
        assert 0, "never happens"
    

    【讨论】:

      【解决方案2】:

      您可以检查 bash 脚本的标准错误,而不是返回代码。

      proc = subprocess.Popen('testing.sh', stdout=subprocess.PIPE, stderr=subprocess.PIPE)
      (stdout, stderr) = proc.communicate()
      if stderr:
         print "Shell script gave some error"
      else:
         print "end" # Shell script ran fine.
      

      【讨论】:

      • 谢谢 Aro,它工作得很好.. 但我没有看到我的 shell 脚本的任何输出.. 如你所见,我的 shell 脚本中有几个 echo 命令.. 这是否意味着我的shell 脚本命令正在执行,但没有打印出来?
      • 您的输出在变量 - 标准输出中。如果要在屏幕上显示,可以使用 stdout=subprocess.STDOUT
      • 谢谢 Aro:所以我可以安全地假设我的 shell 脚本正在执行但结果存储在 stdout 变量中?对吗?
      【解决方案3】:

      好吧,根据the docs,.call 会将退出代码返回给您。不过,您可能需要检查您是否确实收到了错误返回码。 (我认为 for 循环仍然会返回 0 代码,因为它或多或少地完成了。)

      【讨论】:

      • 感谢制表符。您能否提供一个示例,其中 shell 脚本将失败并且退出状态返回为 1 而不是 0.. 只是想了解它是如何工作的。
      • 默认情况下,shell 脚本将返回其最后一个命令的状态。在我的脑海中,一个 for 循环将返回最后一个内部命令的状态,或者,如果循环根本没有运行(如本例所示),则返回 0 表示成功。因此,如果您更改内容以使错误最后发生;或者,如果您在脚本中明确返回 1,您将看到 1 而不是 0。
      猜你喜欢
      • 2013-09-26
      • 2013-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-27
      • 2019-11-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多