为什么这个python脚本不起作用?

时间:2012-02-28 13:50:26

标签: python linux bash

我的python脚本是以下代码:

 1 import subprocess
 2 
 3 # initial 'output' to make
 4 r0 = 21
 5 # number of runs to make
 6 rn = 10
 7 
 8 rf = r0+rn
 9 
10 for i in range(r0, rf):
11   #output directory
12   opt_dir = 'output'+str(i)
13   #put it in this output directory
14   popt_dir = './output'+str(i)
15 
16   subprocess.call(['mkdir', opt_dir])
17   subprocess.call(['./exp_fit', 'efit.inp'])
18   subprocess.call(['mv', 'at*', popt_dir])

意图是:

我有一个名为“exp_fit”的程序,它接受一个输入文件“efit.inp”。一次调用./exp_fit efit.inp将创建名为'at0_l0_l0','at0_l1_l-1',...等的输出文件(共有475个以'at'开头的文件)。

现在,我已经通过运行'exp_fit'生成数据文件,然后使用以下bash命令创建输出目录并将它们移动到输出目录中: (例如,使用我的代码的第20次运行)

mkdir output20

mv at* ./output20

所以我认为我的脚本应该做同样的事情。但是,它只执行以下操作:

(1)它正确生成所有输出文件(以'at'开头的475个文件) (2)它正确创建了所需的目录(output21 - output30) (3)但是,它并没有正确地将所有以'at'开头的输出文件移动到所需的目录中。为什么是这样?第18行的调用是否应该正确执行命令将所有以'at'开头的文件移动到所需的目录中?

我应该用bash而不是python编写这个脚本吗?这有什么问题?

3 个答案:

答案 0 :(得分:5)

不要发出subprocess调用您可以从Python本地执行的操作。要移动文件/目录,只需使用os.rename

要创建目录,请使用os.mkdir

要执行外部程序,使用subprocess 是正确的工具。

答案 1 :(得分:3)

问题是这个子进程命令

subprocess.call(['mv', 'at*', './output20'])

与在提示符下键入此内容不同

$ mv at* ./output20

在后一种情况下,bash glob扩展将单个at*参数转换为mv命令的匹配文件名的参数列表。所以内核将第二个视为

['mv', 'at0_l0_l0', 'at0_l1_l-1', './output20']

kev's answer告诉Python通过shell传递命令,因此将发生转义。

但更好的解决方案是使用glob模块和os.rename库,而不是调用子进程。创建子进程非常昂贵,使用shell=True可能会导致安全漏洞,因此最好避免这种习惯。

(实际上,我建议创建输出目录,切换到它,然后从该目录中运行exp_fit程序。然后你不必移动输出。首先尝试。)

答案 2 :(得分:1)

如果shell=True,可执行参数指定要使用的shell 在Unix上,默认shell为/bin/sh

subprocess.call(['mv', 'at*', popt_dir], shell=True)