我写了一段简单的代码:
import subprocess
p=subprocess.Popen('mkdir -p ./{a,b,c}', shell=True, stderr=subprocess.STDOUT)
p.wait()
不幸的是,它并不总是像我期望的那样。即,当我在我的电脑上运行它时,一切都很好(ls -l给了我三个dirs:a,b和c)。但当我的同事在他的桌面上运行时,他得到了...一个名为'{a,b,c}'的目录...我们都使用Python 2.7.3。这是为什么?你会如何解决它?
我试图自己找到答案。根据手册: “args应该是一系列程序参数或者是一个单独的字符串。默认情况下,如果args是一个序列,则执行的程序是args中的第一项。如果args是一个字符串,则解释依赖于平台,如下所述。请参阅shell和可执行参数以获取与默认行为的其他差异。除非另有说明,否则建议将args作为序列传递。“
所以我尝试在shell中执行代码:
python -c "import subprocess; p=subprocess.Popen(['mkdir', '-p', './{ea,fa,ga}'], shell=True, stderr=subprocess.STDOUT); p.wait()"
我得到了:
mkdir: missing operand
我会感谢任何建议
谢谢!
答案 0 :(得分:2)
./{a,b,c}
语法为bash
语法,并非所有shell都支持。
文档说:
在具有
shell=True
的Unix上,shell默认为/bin/sh
。如果args是 string,string指定通过shell执行的命令。
因此,只有/bin/sh
符号链接到支持该语法的shell(例如bash
或zsh
)时,您的命令才有效。您的同事可能正在使用dash
或其他不支持此功能的shell。
你不应该依赖用户的默认shell。相反,使用完整扩展编写完整命令:
p = subprocess.Popen('mkdir -p ./a ./b ./c', shell=True, stderr=subprocess.STDOUT)
答案 1 :(得分:0)
这里有几个问题。
答案 2 :(得分:0)
谢谢大家的回答。 看来,最好的方法就是使用/ bin / sh语法。我改变了我的代码使用:
'mkdir -p ./a ./b ./c'
正如你的建议。
我避免使用mkdir()函数,因为我正在编写一个包含大量系统调用的脚本,我想提供优雅的--dry-run选项(所以我可以列出所有命令)。
问题解决了 - 谢谢!
答案 3 :(得分:-1)
os.mkdir(path,[mode])方法据我所知在处理多平台项目时更安全。
os.mkdir(os.getcwd()/a)
然而,它并不像采用子流程方法那样优雅。