克服Python 2.3中os.system()的限制
我在把我们公司的一个脚本从csh转换成Python时遇到了问题。这个csh脚本调用了一个别名命令,但当我通过os.system()调用同样的别名命令时,它却不工作。
假设foo
是这个别名命令:
CSH脚本(这个可以正常工作,执行foo):
foo <argument>
Python(这个不行,错误提示说foo是个未知命令):
os.system("foo <argument>")
我觉得在执行Python脚本时,可能发生了某种上下文切换,导致Python无法访问在shell中创建的别名。看了文档后,我发现os.system
正在被逐渐淘汰,取而代之的是subprocess
,而且subprocess
有一个shell
参数,可能能帮到我……问题是我只能用Python 2.3,而subprocess
直到2.4才有。
我想到了在Python中复制这个别名的办法。比如说,假设foo
是别名cp
。
CSH:
alias foo cp
foo file1 file2
Python:
os.system("alias foo cp")
os.system("foo file1 file2")
结果也不行……这里也出错了:
sh: line 0: alias: foo: not found
sh: line 0: alias: cp: not found
sh: foo: command not found
我最后的办法是把使用foo
的几行代码放到一个单独的CSH脚本中,然后让Python去调用这个脚本。但如果有其他办法能解决这个问题,而不需要这样做,我很想知道。
提前谢谢你们!
2 个回答
如果你想在Python中使用“foo”这个别名,那你需要在调用os.system之前自己设置这个别名:
cmd = "foo file1 file2"
foo_alias = "cp"
cmd = re.sub("^foo ", foo_alias + " ", cmd)
os.system(cmd)
如果这个foo别名比较复杂(比如需要替换参数等等),那就可能会更难处理。
你为什么觉得 os.system 会使用 csh 呢?其实它使用的是标准的 C 函数 system,在 Unix 系统上,这个函数会调用基本的 /bin/sh。这个不会是 csh,可能更像是 bash,或者是它的某个简单版本。
顺便说一下,注意在 os.system 中对 shell 环境所做的任何操作不会影响后续的 os.system 调用,因为每次调用都是在不同的子 shell 中运行。换句话说,对环境所做的更改是不会被保留的。而且你调用 alias 失败了,因为 /bin/sh 对于别名的语法和 csh 是不同的。
你可以通过运行一些类似于 foo
的命令来解决这个问题:
os.system("/bin/csh -i -c 'foo arg1 arg2'")
注意选项 -i
,这个选项是用来强制 csh 读取启动脚本的。