Python subprocess.call bash 别名
- 2025-03-05 09:18:00
- admin 原创
- 64
问题描述:
我的 .bashrc 中有一个别名,它调用其他脚本,并向其传递特定的命令行参数。
我想编写一个 python 脚本,每隔几分钟调用一次这个别名,这样我就可以打开一个带有更新统计数据的 shell。
但是subprocess.call("myAlias")
,像这样尝试,失败了:
from subprocess import call
def callAlias():
call("myAlias")
callAlias()
我怎样才能让 Python 使用我的别名.bashrc
?
解决方案 1:
更新:感谢大家对这个解决问题的技巧的点赞,我很高兴它有用。但tripleee 的答案更好。
如果您需要的别名是在 ~/.bashrc 中定义的,那么它将不会运行,原因如下:
您必须给出
shell
关键字 arg:
subprocess.call('command', shell=True)
否则,您给出的命令将用于查找可执行文件,而不是传递给 shell,并且 shell 会扩展别名和函数等内容。
默认情况下,
subprocess.call
和朋友使用/bin/sh
shell。如果这是您想要调用的 Bash 别名,则需要使用executable
关键字 arg 告诉 subprocess 使用 bash 而不是 sh:
subprocess.call('command', shell=True, executable='/bin/bash')
但是,除非作为“交互式”shell(使用
-i
.)启动,否则 /bin/bash 将不会获取 ~/.bashrc。不幸的是,您无法传递executable='/bin/bash -i'
,因为它认为整个值是可执行文件的名称。因此,如果您的别名是在用户的正常交互式启动中定义的,例如在 .bashrc 中,那么您必须使用以下替代形式调用该命令:
subprocess.call(['/bin/bash', '-i', '-c', command])
# i.e. shell=False (the default)
解决方案 2:
您需要将shell
关键字设置为 True:
call("myAlias", shell=True)
来自相关文献:
如果
shell
是True
,则指定的命令将通过 shell 执行。如果您使用 Python 主要是为了获得它在大多数系统 shell 上提供的增强控制流,并且仍想访问其他 shell 功能(如文件名通配符、shell 管道和环境变量扩展),那么这将非常有用。
别名是 shell 的一个特性(例如,它们由 shell 定义和解释)。
但是,shell(/bin/sh)是非交互执行的,因此不会读取.profile
任何.bashrc
文件,并且您的别名可能不可用。
如果你不愿意在你的 Python 脚本中使用完整的扩展命令,你必须使用$ENV
环境变量来让 Shell 读取其中定义的别名的文件:
call("myAlias", shell=True, env=dict(ENV='/path/to/aliasfile'))
解决方案 3:
建议的解决方案是不要使用别名来定义非专门用于交互使用的功能(即使这样,shell 函数在许多方面也更胜一筹)。
将别名重构为独立脚本并像任何其他外部命令一样调用它。
更详细地说,如果你有
alias myalias='for x in foo bar baz; do
frobnicate "$x"; done'
你可以改进它,这样它就不会通过把它变成一个函数来污染你的全局命名空间
myalias () {
local x
for x in foo bar baz; do
frobnicate "$x"
done
}
或者仅将其另存为 /usr/local/bin/myalias
并chmod a+x /usr/local/bin/myalias
使其可供所有人执行;
#!/bin/sh
for x in foo bar baz; do
frobnicate "$x"
done
(这在子进程中运行,因此x
当脚本完成时它就会消失;所以我们不需要这样做local
。)
(当然,如果frobnicate
写得足够好,也许你可以简化得frobnicate foo bar baz
同样好。)
这是一个常见的常见问题解答。
解决方案 4:
我稍微修改了 Jonathan 的理由 #2,让它工作起来。创建一个/usr/local/bin/interactive_bash
包含以下内容的文件
#!/bin/bash
/bin/bash -i "$@"
然后chmod +x
你可以从 Python 调用
subprocess.call('my_alias', shell=True, executable='/usr/local/bin/interactive_bash')
扫码咨询,免费领取项目管理大礼包!