Python subprocess.call一个bash别名

时间:2012-08-21 18:26:41

标签: python bash subprocess

在工作中有一个列出已完成任务的脚本。这是由其他人编写的,并通过网络托管。我的.bashrc中有一个别名,它调用了这个脚本,有很多标志等等,我想编写一个python脚本,每隔几分钟调用一次这样的别名,这样我就可以打开一个带有更新统计数据的shell。但是,subprocess.call("myAlias")失败。我对python仍然相当新,我正在努力解决这个问题。

from subprocess import call

def callAlias():
    call("myAlias")

callAlias()

我计划增加更多,但我在第一步遇到障碍。 :P

我会发布更多内容,但我需要注意很多敏感的机密内容。很抱歉模糊的代码和错误输出。

4 个答案:

答案 0 :(得分:57)

如果您需要的别名在〜/ .bashrc中定义,那么它不会因为以下几个原因而运行:

1)你必须给出' shell'关键字arg:

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

否则,您的给定命令用于查找可执行文件,而不是传递给shell,而它是扩展别名和函数之类的shell。

2)默认情况下,subprocess.call和朋友使用' / bin / sh'贝壳。如果这是您想要调用的Bash别名,则您需要告诉子进程使用bash而不是sh,使用'可执行文件'关键字arg:

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

3)然而,/ bin / bash不会提供〜/ .bashrc,除非以“交互式”开头。 shell(使用' -i'。)很遗憾,您无法传递executable =' / bin / bash -i',因为它认为整个值是一个名称可执行文件。因此,如果您的别名是在用户的正常交互式启动中定义的,例如在.bashrc中,您必须使用以下替代形式调用命令:

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

答案 1 :(得分:20)

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

call("myAlias", shell=True)

来自relevant documentation

  

如果shellTrue,则将通过shell执行指定的命令。如果您主要使用Python来提供它在大多数系统shell上提供的增强控制流,并且仍然希望访问其他shell功能,例如文件名通配符,shell管道和环境变量扩展,那么这将非常有用。

别名是一个shell特性(例如,它们由shell定义和解释)。

但是,shell(/ bin / sh)是以非交互方式执行的,因此不会读取.profile.bashrc个文件,并且您的别名可能无法使用。

如果您不愿意将完整的扩展命令用于python脚本,则必须使用$ENV environment variable使shell读取其中定义了别名的文件:

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

答案 2 :(得分: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/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。)

这是一个常见的常见问题解答。

答案 3 :(得分:2)

我稍微修改了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')