简体   繁体   English

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

[英]store return value of a Python script in a bash script

I want to execute a python script from a bash script, and I want to store the output of the python script in a variable. 我想从bash脚本执行一个python脚本,我想将python脚本的输出存储在一个变量中。

In my python script, I print some stuff to screen and at the end I return a string with: 在我的python脚本中,我将一些东西打印到屏幕上,最后我返回一个字符串:

sys.exit(myString) 

In my bash script, I did the following: 在我的bash脚本中,我执行了以下操作:

outputString=`python myPythonScript arg1 arg2 arg3 `

But then when I check the value of outputString with echo $outputString I get everything that the Python script had printed to screen, but not the return value myString ! 但是当我用echo $outputString检查outputString的值时,我得到了Python脚本打印到屏幕的所有内容,但没有返回值myString

How should I do this? 我该怎么做?

EDIT: I need the string because that tells me where a file created by the Python script is located. 编辑:我需要字符串,因为它告诉我Python脚本创建的文件位于何处。 I want to do something like: 我想做的事情如下:

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

sys.exit(myString) doesn't mean "return this string". sys.exit(myString)并不意味着“返回此字符串”。 If you pass a string to sys.exit , sys.exit will consider that string to be an error message, and it will write that string to stderr . 如果将字符串传递给sys.exitsys.exit会将该字符串视为错误消息,并将该字符串写入stderr The closest concept to a return value for an entire program is its exit status , which must be an integer. 与整个程序的返回值最接近的概念是其退出状态 ,该状态必须是整数。

If you want to capture output written to stderr, you can do something like 如果要捕获写入stderr的输出, 可以执行类似的操作

python yourscript 2> return_file

You could do something like that in your bash script 您可以在bash脚本中执行类似的操作

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

This is not guaranteed to capture only the value passed to sys.exit , though. 但是,不能保证仅捕获传递给sys.exit的值。 Anything else written to stderr will also be captured, which might include logging output or stack traces. 还将捕获写入stderr的任何其他内容,其中可能包括日志记录输出或堆栈跟踪。

example: 例:

test.py test.py

print "something"
exit('ohoh') 

t.sh t.sh

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

bash t.sh

edit 编辑

Not sure why but in that case, I would write a main script and two other scripts... Mixing python and bash is pointless unless you really need to. 不知道为什么,但在那种情况下,我会写一个主脚本和另外两个脚本...混合python和bash是没有意义的,除非你真的需要。

import script1
import script2

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

sys.exit() should return an integer, not a string: sys.exit()应该返回一个整数,而不是一个字符串:

sys.exit(1)

The value 1 is in $? 1$? .

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

Edit: 编辑:

If you want to write to stderr, use sys.stderr . 如果要写入stderr,请使用sys.stderr

Do not use sys.exit like this. 不要像这样使用sys.exit When called with a string argument, the exit code of your process will be 1, signaling an error condition. 使用字符串参数调用时,进程的退出代码将为1,表示错误情况。 The string is printed to standard error to indicate what the error might be. 打印字符串为标准错误,以指示错误可能是什么。 sys.exit is not to be used to provide a "return value" for your script. sys.exit不能用于为脚本提供“返回值”。

Instead, you should simply print the "return value" to standard output using a print statement, then call sys.exit(0) , and capture the output in the shell. 相反,您应该使用print语句将“返回值”打印到标准输出,然后调用sys.exit(0) ,并捕获shell中的输出。

read it in the docs . 文档中阅读它。 If you return anything but an int or None it will be printed to stderr . 如果你返回除intNone任何东西,它将被打印到stderr

To get just stderr while discarding stdout do: 要在丢弃标准输出时获得stderr,请执行以下操作:

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

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

The optional argument arg can be an integer giving the exit status (defaulting to zero), or another type of object. 可选参数arg可以是一个整数,给出退出状态(默认为零)或其他类型的对象。 If it is an integer, zero is considered “successful termination” and any nonzero value is considered “abnormal termination” by shells and the like. 如果它是整数,则零被认为是“成功终止”,并且任何非零值被贝壳等视为“异常终止”。 Most systems require it to be in the range 0-127, and produce undefined results otherwise. 大多数系统要求它在0-127范围内,否则会产生不确定的结果。

Moreover to retrieve the return value of the last executed program you could use the $? 此外,要检索上次执行的程序的返回值,您可以使用$? bash predefined variable. bash预定义变量。

Anyway if you put a string as arg in sys.exit() it should be printed at the end of your program output in a separate line, so that you can retrieve it just with a little bit of parsing. 无论如何,如果你把一个字符串作为arg放在sys.exit()中,它应该在程序输出的末尾打印在一个单独的行中,这样你只需要进行一些解析就可以检索它。 As an example consider this: 举个例子考虑一下:

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

除了Tichodroma所说的,你最终可能会使用这种语法:

outputString=$(python myPythonScript arg1 arg2 arg3)

You answered your own question. 你是在自问自答。 If you want to run a Python script from bash and store the output in a bash variable, be selective in what your Python script prints. 如果要从bash运行Python脚本并将输出存储在bash变量中,请选择Python脚本打印的内容。

Make a "verbose" flag that you can turn off in your Python script to suppress extra text that you don't want stored in your bash variable. 创建一个“详细”标记,您可以在Python脚本中关闭该标记以禁止您不希望存储在bash变量中的额外文本。 Don't get involved in writing valid output to stderr or overriding exit codes! 不要参与将有效输出写入stderr或覆盖退出代码! (that's what the bad kids do...) (这就是坏孩子们所做的......)

Try something like this: 尝试这样的事情:

fileLocation=`python myPythonScript1 arg1 arg2 arg1 --verbose off`

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM