2013-04-01 54 views
2

如何将命令作为参数传递给bash脚本? 在下面的脚本中,我试图做到这一点,但它不起作用!将命令作为参数传递给bash脚本

#! /bin/sh 

if [ $# -ne 2 ] 
then 
    echo "Usage: $0 <dir> <command to execute>" 
    exit 1; 
fi; 

while read line 
do 
    $($2) $line 
done < $(ls $1); 

echo "All Done" 

该脚本的样本用法是

./myscript thisDir echo 

执行上述呼吁应该呼应的所有文件的名称中thisDir目录。

+0

尝试'EVAL “$ 2”' - http://www.linuxquestions.org/questions/programming-9/bash-script-passing-command-as-string-476664/ –

+0

@DavidStarkey嗯,我试过'eval'(以及下面建议的与'eval'有关的pther解决方案),都没有工作。 –

回答

0

你可以尝试:(在你的代码)

echo "$2 $line"|sh 

eval

eval "$2 $line" 
+0

不适合我。当我用'myscript thisDir cat'调用脚本时,这意味着它应该'cat'指向目录中的所有文件,它没有 –

+0

任何错误信息? – Kent

+0

不,没有任何错误。当我运行脚本时,它只是列出了目录中的所有文件,尽管我确实指定了“cat”作为命令。 –

1

你的命令 “echo” 命令是 “隐藏” 在其argments子壳内$线。

我想我明白你什么企图与$($2),但它可能是矫枉过正,除非这并不是故事的全部,所以

while read line ; do 
    $2 $line 
done < $(ls $1) 

应与thisDir echo你的榜样工作。如果你真的需要CMD-替代和子shell,然后把你的论点,使他们能够看到对方:

$($2 $line) 

而作为D.S.提到,您可能需要eval任一前。

IHTH

0

第一大问题:$($2) $line本身执行$2作为命令,然后尝试与$line作为参数传递给它运行它的输出(如果有的话)作为另一个命令。你只需要$2 $line

第二大问题:while read ... done < $(ls $1)不会从文件名列表中读取,它会尝试输出ls指定的文件内容 - 根据具体情况,这会以任何方式失败。进程替换(while read ... done < <(ls $1))会做或多或少的你想要的,但它是一个仅限bash的功能(即你的必须启动脚本#!/bin/bash而不是#!/bin/sh)。无论如何这对parse ls是一个坏主意,你应该几乎总是使用shell glob(*)代替。

该脚本还有一些其他潜在的问题与文件名空间(使用$line没有双引号周围,等),怪异的风格怪异(你不需要;在shell行中的末尾)。这里是我的刺在改写:

#! /bin/sh 

if [ $# -ne 2 ]; then 
    echo "Usage: $0 <dir> <command to execute>" 
    exit 1 
fi 

for file in "$1"/*; do 
    $2 "$file" 
done 

echo "All done" 

注意,我没把周围$2双引号。这允许您指定多字命令(例如,./myscript thisDir "cat -v"将被解释为运行带有-v选项的cat命令,而不是尝试运行名为"cat -v"的命令)。将第一个参数之后的所有参数作为命令及其参数,实际上会更灵活一些,从而可以让您./myscript thisDir cat -v,​​等:

#! /bin/sh 

if [ $# -lt 2 ]; then 
    echo "Usage: $0 <dir> <command to execute> [command options]" 
    exit 1 
fi 

dir="$1" 
shift 

for file in "$dir"/*; do 
    "[email protected]" "$file" 
done 

echo "All done" 
相关问题