Python subprocess.call bash别名

Python subprocess.call bash别名,python,bash,subprocess,Python,Bash,Subprocess,在工作中,有一个列出已完成任务的脚本。这是由其他人编写的,并通过网络托管。我在.bashrc中有一个别名,它调用这个脚本,有很多标志等等,我想编写一个python脚本,每隔几分钟调用一次这个别名,这样我就可以打开一个shell,其中包含更新的统计信息。但是,subprocess.call(“myAlias”)失败。我对python还是相当陌生的,并且正在努力解决这个问题 from subprocess import call def callAlias(): call("myAlias

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

from subprocess import call

def callAlias():
    call("myAlias")

callAlias()
我也计划增加更多,但我在第一步就遇到了困难P


我会发布更多,但是有很多敏感的机密信息我必须小心处理。很抱歉代码模糊,并且没有错误输出。

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

call("myAlias", shell=True)
从:

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

别名是外壳特征(例如,它们由外壳定义和解释)

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

如果您不愿意在python脚本中使用完全展开的命令,则必须使用命令行使shell读取其中定义了别名的文件:

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

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

call("myAlias", shell=True)
从:

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

别名是外壳特征(例如,它们由外壳定义和解释)

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

如果您不愿意在python脚本中使用完全展开的命令,则必须使用命令行使shell读取其中定义了别名的文件:

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

更新:感谢您的支持,帮助我们解决了这个问题,我很高兴它很有用。但一个更好的答案是tripleee的,在页面的下方久久不见

如果您需要的别名是在~/.bashrc中定义的,那么它将无法运行,原因如下:

1) 您必须提供“shell”关键字参数:

subprocess.call('command', shell=True)
subprocess.call('command', shell=True, executable='/bin/bash')
否则,给定的命令将用于查找可执行文件,而不是传递给shell,而shell将扩展别名和函数等内容

2) 默认情况下,subprocess.call和friends使用“/bin/sh”shell。如果这是要调用的Bash别名,则需要使用'executable'关键字arg告诉子流程使用Bash而不是sh:

subprocess.call('command', shell=True)
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)

更新:感谢您的支持,帮助我们解决了这个问题,我很高兴它很有用。但一个更好的答案是tripleee的,在页面的下方久久不见

如果您需要的别名是在~/.bashrc中定义的,那么它将无法运行,原因如下:

1) 您必须提供“shell”关键字参数:

subprocess.call('command', shell=True)
subprocess.call('command', shell=True, executable='/bin/bash')
否则,给定的命令将用于查找可执行文件,而不是传递给shell,而shell将扩展别名和函数等内容

2) 默认情况下,subprocess.call和friends使用“/bin/sh”shell。如果这是要调用的Bash别名,则需要使用'executable'关键字arg告诉子流程使用Bash而不是sh:

subprocess.call('command', shell=True)
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)

我稍微修改了Jonathan的reason#2,以使其起作用。制作一个包含以下内容的
/usr/local/bin/interactive\u bash
文件

#!/bin/bash
/bin/bash -i "$@"
chmod+x
it。然后可以从Python调用

subprocess.call('my_alias', shell=True, executable='/usr/local/bin/interactive_bash')

我稍微修改了Jonathan的reason#2,以使其起作用。制作一个包含以下内容的
/usr/local/bin/interactive\u bash
文件

#!/bin/bash
/bin/bash -i "$@"
chmod+x
it。然后可以从Python调用

subprocess.call('my_alias', shell=True, executable='/usr/local/bin/interactive_bash')

建议的解决方案是,不要使用别名来定义不专用于交互使用的功能(即使如此,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

(当然,如果
frobnite
写得很好,也许你也可以简化为
frobnite foo bar baz
。)

这是一个