Python 的 sh 模块 - 运行“源”命令

use*_*542 2 python

使用 python 的sh模块时,我想运行一个“源”内置命令。

但是我不能运行它,因为 sh 应该有一个二进制文件作为参数。

如何使用 sh 模块运行内置命令?

# source ./test.sh

sh.source('./test.sh') # wrong usage
sh.Command('source') # wrong usage
Run Code Online (Sandbox Code Playgroud)

Cha*_*ffy 5

sh -c "source hello"通过 Pythonsh模块调用(忽略sh不保证完全支持该source命令——符合 POSIX 标准的等价物是. hello):

sh.sh('-c', 'source test.sh')
Run Code Online (Sandbox Code Playgroud)

也就是说,考虑使用subprocess.Popen()它,它包含的魔法少得多,因此行为更可预测:

# ...if hardcoding the script to source in your Python code
# ...because shell=True uses /bin/sh instead of bash, use . instead of source
subprocess.Popen('. ./test.sh', shell=True)

# ...otherwise:
# ...because shell=True uses /bin/sh instead of bash, use . instead of source
subprocess.Popen(['. "$@"', './test.sh'], shell=True)
Run Code Online (Sandbox Code Playgroud)

当一个阵列被传递到的第一个参数subprocess.Popen,所述第一参数作为源来运行,及以后的参数成为$1$2等,其脚本的操作过程中,允许字符串文字的阵列的组合与/bin/sh经由所调用的shell=True


但是:将内容采购到 shell 背后的意图和目的通常是修改该 shell 的状态。使用sh.shsubprocess.Popen(),shell 的持续时间仅与单个 Python 函数调用的调用一样长,因此没有状态会持续到未来shsubprocess调用,因此这些用途中的任何一个都不太可能真正实现您手头的目标。

真正想要的可能更像这样:

sh.sh('-c', '. ./test.sh; do-something-else-here')
Run Code Online (Sandbox Code Playgroud)

...其中您do-something-else-here依赖于对 shell 及其环境所做的更改source ./test.sh