将命令作为参数传递给bash脚本

时间:2013-04-01 18:49:50

标签: 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目录中所有文件的名称。

3 个答案:

答案 0 :(得分:1)

你的命令“echo”命令在$ line中从它的argments中隐藏在子shell中。

我想我理解你在$($2)尝试了什么,但它可能有点过分,除非这不是整个故事,所以

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

应该适用于thisDir echo的示例。如果你真的需要cmd-substitution和subshel​​l,那么就把你的参数放在一起,这样他们就能看到对方:

   $($2 $line)

正如D.S.提到的那样,在其中任何一个之前你可能需要eval

IHTH

答案 1 :(得分:0)

您可以尝试:(在您的代码中)

echo "$2 $line"|sh

eval

eval "$2 $line"

答案 2 :(得分:0)

第一个大问题:$($2) $line自己执行$2作为命令,然后尝试将其输出(如果有的话)作为另一个命令运行$line作为参数。你只想要$2 $line

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

该脚本还有一些其他潜在的问题,包括文件名中的空格(使用*而没有双引号等),以及奇怪的风格怪异(最后不需要$line壳中的一条线)。这是我重写的重点:

;

请注意,我没有在#! /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"选项运行cat命令,而不是尝试运行名为-v的命令。将第一个参数作为命令及其参数后的所有参数实际上会更灵活一些,允许您进行例如"cat -v"./myscript thisDir cat -v等:

./myscript thisDir grep -m1 "pattern with spaces"