Python调用bash别名命令返回非零码问题排查与解决
问题原因
bash在非交互模式(比如通过bash -c执行命令时)默认不启用别名扩展,哪怕你source了定义别名的脚本,别名也不会被激活。这就导致command -v testcommand找不到对应的别名,返回码为1。而你直接在终端里执行时,bash是交互模式,默认会启用别名扩展,所以能正常识别别名,返回码0。
解决方案
要在非交互的bash会话中启用别名扩展,有两种可行方法,都不需要修改你提到的/bin/bash -c或subprocess.Popen的shell=False参数:
方法1:给bash添加-O expand_aliases选项
修改Python代码中的bash命令,让bash启动时就开启别名扩展:
import os import subprocess path_home = os.path.expanduser('~') # 添加-O expand_aliases开启别名扩展 proc = subprocess.Popen( ['/bin/bash', '-O', 'expand_aliases', '-c', 'source %s/define_alias.sh; command -v testcommand' % path_home], shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) proc_stdout, proc_stderr = proc.communicate() proc_returncode = proc.returncode print("Returncode: %s" % proc_returncode) print("Stdout: %s" % proc_stdout) print("Stderr: %s" % proc_stderr)
方法2:在source脚本后执行shopt -s expand_aliases
如果不想修改bash的启动参数,可以在shell命令串里添加开启别名扩展的命令:
import os import subprocess path_home = os.path.expanduser('~') # 在source后添加shopt -s expand_aliases启用别名 proc = subprocess.Popen( ['/bin/bash', '-c', 'source %s/define_alias.sh; shopt -s expand_aliases; command -v testcommand' % path_home], shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) proc_stdout, proc_stderr = proc.communicate() proc_returncode = proc.returncode print("Returncode: %s" % proc_returncode) print("Stdout: %s" % proc_stdout) print("Stderr: %s" % proc_stderr)
验证效果
两种方法执行后,都会得到返回码0,且stdout会输出alias testcommand='echo THIS IS A TEST',和你直接在终端执行的结果一致。
内容的提问来源于stack exchange,提问作者silence_of_the_lambdas
相关产品推荐
相关产品推荐

