将 Python 脚本的返回值存储在 bash 脚本中

Posted

技术标签:

【中文标题】将 Python 脚本的返回值存储在 bash 脚本中【英文标题】:store return value of a Python script in a bash script 【发布时间】:2012-08-07 16:57:11 【问题描述】:

我想从 bash 脚本执行 python 脚本,并且我想将 python 脚本的输出存储在一个变量中。

在我的 python 脚本中,我将一些内容打印到屏幕上,最后我返回一个字符串:

sys.exit(myString) 

在我的 bash 脚本中,我执行了以下操作:

outputString=`python myPythonScript arg1 arg2 arg3 `

但是当我用echo $outputString 检查outputString 的值时,我得到了Python 脚本打印到屏幕上的所有内容,但不是返回值myString

我应该怎么做?

编辑:我需要该字符串,因为它告诉我 Python 脚本创建的文件所在的位置。我想做类似的事情:

fileLocation=`python myPythonScript1 arg1 arg2 arg1`
python myPythonScript2 $fileLocation

【问题讨论】:

您是否尝试仅从您的 python 命令打印并将其设置为变量而不执行任何系统退出?例如local_dir=$(python execute_tensorboard.py $1)? 【参考方案1】:

sys.exit() 应该返回一个整数,而不是字符串:

sys.exit(1)

1 的值在$? 中。

$ cat e.py
import sys
sys.exit(1)
$ python e.py
$ echo $?
1

编辑:

如果要写入 stderr,请使用 sys.stderr

【讨论】:

$? 可以被 shell 脚本用来检查前一个命令是否正常工作或是否有错误。退出码是Un*x环境下程序进行通信的基本方式。 $?是返回码。它用于知道脚本是否正确完成。它是如何工作的,你可以返回 0 == 'fine', 1=> error, 2=>Some specific error etc... Tichodroma,实际上 sys.exit 允许字符串 args 将它们输出到 stderr。 @LoïcFaure-Lacroix 是的,但我建议不要使用它。【参考方案2】:

除了 Tichodroma 所说的,您最终可能会使用以下语法:

outputString=$(python myPythonScript arg1 arg2 arg3)

【讨论】:

【参考方案3】:

sys.exit(myString) 并不意味着“返回这个字符串”。如果您将字符串传递给sys.exitsys.exit 将认为该字符串是错误消息,并将该字符串写入stderr。与整个程序的返回值最接近的概念是它的exit status,它必须是一个整数。

如果要捕获写入 stderr 的输出,you can do something like

python yourscript 2> return_file

你可以在你的 bash 脚本中做类似的事情

output=$((your command here) 2> &1)

但不能保证只捕获传递给sys.exit 的值。写入 stderr 的任何其他内容也将被捕获,其中可能包括日志输出或堆栈跟踪。

示例:

test.py

print "something"
exit('ohoh') 

t.sh

va=$(python test.py 2>&1)                                                                                                                    
mkdir $va

bash t.sh

编辑

不知道为什么,但在这种情况下,我会编写一个主脚本和两个其他脚本...混合 python 和 bash 是没有意义的,除非你真的需要。

import script1
import script2

if __name__ == '__main__':
    filename = script1.run(sys.args)
    script2.run(filename)

【讨论】:

这一切都有效。但我建议使用整数退出代码来让脚本在 Un*x 环境中运行良好。 嗯。你为什么要2>2 是干什么用的?我需要做的就是检索我的 python 脚本创建并写入的文件的位置,但我无法关闭所有打印。 > 是一个重定向运算符。 2> 重定向错误信息,> 单独是标准输出 < 是标准输入 @RickyRobinson 也许你找错地方了。请在您的问题中阐明您的目标,以便我们建议实现目标的最佳方法。 问题是,既然你用sys.exit写信给stderr。不确定那里不会写其他任何内容。【参考方案4】:

sys.exit([arg]) 的 Python 文档说:

可选参数 arg 可以是给出退出状态的整数(默认为零),或其他类型的对象。如果它是一个整数,则零被认为是“成功终止”,任何非零值都被 shell 等视为“异常终止”。大多数系统要求它在 0-127 范围内,否则会产生未定义的结果。

此外,要检索最后执行程序的返回值,您可以使用 $? bash 预定义变量。

无论如何,如果您将字符串作为 arg 放入 sys.exit() 中,它应该在程序输出的末尾打印在单独的行中,以便您只需稍作解析即可检索它。举个例子:

outputString=`python myPythonScript arg1 arg2 arg3 | tail -0`

【讨论】:

@Ricky Robinson 考虑只使用 tail -0。它应该像您在编辑的问题中所说的那样工作。然后别忘了给答案打分。 @Alp 您的答案列表是另一种命令替换语法。这只是 Ricky Robinson 在问题中使用的语法的别名。请注意! Python 文档还说,如果将字符串作为参数提供给 sys.exit() ,则会将其视为错误消息。这意味着(在 linux/unix 系统中)它被发送到 stderr。如果您的 bash(像大多数人一样)将 stderr 与终端绑定,您应该在脚本输出的末尾看到您的字符串,您可以简单地用 tail 检索它。为了更优雅地获得相同的结果,您可以使用 sys.stderr("your message") 然后使用 sys.exit(0)。 谢谢。也许我应该在包含我的价值之前清除sys.stderr,你怎么看?有什么办法可以做到吗? 感谢@Giova 的想法。就我而言,它适用于tail -1(我可以得到最后一行)【参考方案5】:

在docs 中阅读。 如果您返回除intNone 之外的任何内容,它将被打印到stderr

要在丢弃标准输出的同时获得标准错误,请执行以下操作:

output=$(python foo.py 2>&1 >/dev/null)

【讨论】:

这行得通,但它解决了错误的问题。通过将字符串传递给sys.exit,您隐含地说您的脚本使用退出代码 1 失败。【参考方案6】:

不要像这样使用sys.exit。当使用字符串参数调用时,进程的退出代码将为 1,表示出现错误情况。该字符串被打印为标准错误以指示错误可能是什么。 sys.exit 不能用于为您的脚本提供“返回值”。

相反,您应该使用print 语句将“返回值”打印到标准输出,然后调用sys.exit(0),并在shell 中捕获输出。

【讨论】:

以上是关于将 Python 脚本的返回值存储在 bash 脚本中的主要内容,如果未能解决你的问题,请参考以下文章

bash shell 的返回值

Bash 脚本:避免空字符串参数

将python脚本的输出返回到bash变量[重复]

Bash 脚本将命令输出存储到变量中

bash脚本返回值应用

在 Bash 中,选项标志值如何存储在变量中? [复制]