2016-08-08 25 views
1

我想在固定数量的处理器上动态运行一些进程。我想将输出打印到每个进程的唯一文件,但是xargs没有使用就地文件名为每个进程创建单独的文件时出现问题。发送命令输出到一个独特的文件在Bash中使用xargs

的bash脚本调用csh脚本并低于:

$ cat temp | xargs -P 8 % csh '%'.csh >& '%'.log 

如果温度是csh命令名称的文本文件。

我的问题是,xargs需要%.log字面上和不断覆盖文件的过程写入它,而不是根据需要单独的.log文件。

我运行该脚本$ bash run.bash &

回答

0

一般情况下,使用字符串替换替换到代码是一个坏主意 - 在你的情况,如果你有一个脚本恶意的名称,该名称可以用来运行任意命令。 (当然,你正在执行这个脚本,但是在纯粹处理数据和输出文件名的情况下也是如此 - 所以最好养成一种健壮的方法)。

传递名称作为参数的脚本,而不是代他们到脚本(如xargs会做,如果你加入-I-J参数固定的用法:

# best-practice approach: run a completely fixed shell script, passing arguments on 
# its command line. 
xargs -P 8 -n 1 \ 
    sh -c 'for x; do csh "${x}.csh" >"${x}.log" 2>&1; done' _ 

你请注意,有一个sh -c实例被调用:这是必需的,因为xargs本身不理解shell操作,例如重定向;如果您想要执行重定向,则需要一个shell才能执行。


现在,让我们多一点到,为什么你的原码的表现,因为它没有:

xargs -P 8 % csh '%'.csh >& '%'.log 

... 第一执行重定向到%.log然后运行命令

xargs -P 8 % csh '%'.csh 

xargs没有机会取代%.log因为该重定向是在命令完全运行之前由封装外壳执行的。

+0

感谢您的详细解答。 –

+0

@WillPhilpott,如果这可以解决您的问题,请考虑点击答案旁边的复选框以标记已回答的问题。 –

0

使用GNU并行它看起来像这样:

cat temp | parallel -P 8 'csh {}.csh >& {}.log' 

如果你有8个内核,你甚至可以做:

cat temp | parallel 'csh {}.csh >& {}.log' 

GNU并行报价{}从而不会被执行恶意输入。

相关问题