Python的subprocess.call一个bash别名(Python subprocess.c

2019-06-17 19:37发布

在工作中有一个脚本,列出完成的任务。 这是别人写的,并托管在网络上。 我在我的.bashrc别名调用此脚本,与它的许多标志和这样的,我想写一个python脚本,将调用这个别名每隔几分钟,所以我可以有更新的统计数据打开外壳。 然而, subprocess.call("myAlias")失败。 我仍然相当新的蟒蛇,和我在努力想出解决办法。

from subprocess import call

def callAlias():
    call("myAlias")

callAlias()

我打算增加更多的过它,但我打的障碍在我的第一步。 :P

我会发布更多,但有很多的敏感机密的东西,我必须要小心。 很抱歉的模糊代码,并且缺乏错误输出的。

Answer 1:

如果你需要的别名在〜/ .bashrc定义,那么就不会得到几个原因来看:

1)你必须把“壳”关键字ARG:

subprocess.call('command', shell=True)

否则,你定的命令是用来查找可执行文件,而不是传递到外壳,并且它是扩展之类的别名和功能的外壳。

2)默认情况下,subprocess.call和朋友使用 '/ bin / sh的' 壳。 如果这是你要调用一个猛砸别名,你需要告诉子进程使用bash,而不是SH,使用“可执行”关键字ARG:

subprocess.call('command', shell=True, executable='/bin/bash')

3)但是,/斌/ bash将不会源的〜/ .bashrc,除非开始作为一个“互动”壳(与“-i”)。不幸的是,你不能传递可执行=“/斌/庆典-i”,如它认为整个价值是一个可执行文件的名称。 所以,如果你的别名,在用户的正常互动的启动定义,例如,在.bashrc里,那么你就必须使用这种替换形式调用命令:

subprocess.call(['/bin/bash', '-i', '-c', command])
# i.e. shell=False (the default)


Answer 2:

您需要将设置shell关键字为True:

call("myAlias", shell=True)

从相关文件 :

如果shellTrue ,则指定命令将通过shell执行。 这可以,如果你正在使用Python主要用于增强的控制流它提供了最系统外壳和仍希望访问其他外壳的功能,如文件名通配符,壳管和环境变量扩充是有用的。

别名是一个壳特征(例如,它们被定义壳和解释)。

然而,外壳(/ bin / sh的)执行非交互的,所以没有.profile.bashrc文件的读取和您的别名可能不会用。

如果你不愿意使用完整的扩展命令到您的Python脚本,你必须使用$ENV环境变量 ,使外壳读取反正它定义别名的文件:

call("myAlias", shell=True, env=dict(ENV='/path/to/aliasfile'))


Answer 3:

推荐的解决方案是不使用的别名来定义的功能是不排他地用于交互使用(即使如此,壳功能在许多方面优于)。

重构别名成一个独立的脚本,并调用它像任何其他外部命令。

详细地说,如果你有

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/myaliaschmod 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为好。)

这是一种常见的常见问题。



Answer 4:

我修改乔纳森的理由#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')


文章来源: Python subprocess.call a bash alias