传递Bash变量给脚本?

13

如何最佳地将bash变量传递给Python脚本?我想做类似以下的事情:

$cat test.sh
#!/bin/bash

foo="hi"
python -c 'import test; test.printfoo($foo)'

$cat test.py
#!/bin/python

def printfoo(str):
    print str

当我尝试运行bash脚本时,我遇到了语法错误:

  File "<string>", line 1
    import test; test.printfoo($foo)
                               ^
SyntaxError: invalid syntax
4个回答

14

您可以使用os.getenv从Python中访问环境变量:

import os
import test
test.printfoo(os.getenv('foo'))

然而,为了让Bash中的环境变量传递给它创建的任何进程,您需要使用 export 命令进行导出:

foo="hi"
export foo
# Alternatively, the above can be done in one line like this:
# export foo="hi"

python <<EOF
import os
import test
test.printfoo(os.getenv('foo'))
EOF
作为使用环境变量的替代方案,你可以直接在命令行上传递参数。在-c 命令之后传递给Python的任何选项都会加载到sys.argv数组中:
# Pass two arguments 'foo' and 'bar' to Python
python - foo bar <<EOF
import sys
# argv[0] is the name of the program, so ignore it
print 'Arguments:', ' '.join(sys.argv[1:])
# Output is:
# Arguments: foo bar
EOF

9
简而言之,这是有效的:
...
python -c "import test; test.printfoo('$foo')"
...

更新:

如果您认为该字符串可能包含单引号('),如下面评论中的@Gordon所说,您可以在bash中很容易地转义这些单引号。在这种情况下,这里是一个替代方案:

...
python -c "import test; test.printfoo('"${foo//\'/\\\'}"');"
...

2
如果$foo包含任何单引号或其他Python解释为字面量内部的字符,则此操作会出现有趣的失败。@Adam的解决方案更加健壮... - Gordon Davisson

3

使用argv处理。这样你就不必从解释器中导入它然后运行它。

test.py

import sys

def printfoo(string):
    print string

if __name__ in '__main__':
    printfoo(sys.argv[1])

python test.py testingout

我希望直接调用 printfoo 函数,因为我有很多其他需要从 bash 调用的 Python 函数,它们都需要传递参数。如果我为它们都创建 main 函数,会更复杂。 - Ravi

1

在bash中,您必须使用双引号才能进行变量替换。类似于PHP。

$ foo=bar
$ echo $foo
bar
$ echo "$foo"
bar
$ echo '$foo'
$foo

因此,这应该可以工作:

python -c "import test; test.printfoo($foo)"

1
那样做更进一步了,但现在Python端出现了一个错误,它说NameError: name 'hi' is not defined。 - Ravi
无法编辑,但是对于查看此问题和在我上面的评论的任何人来说,答案是将$foo放在Python代码段中单引号中,否则它将被读取为未定义的变量名bar,因此会出现NameError。因此 python -c“import test; test.printfoo('$foo')”,现在您将打印所需的字符串'bar'。 - Coffee_Table

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接