接受可变数量的参数并执行它们

接受可变数量的参数并执行它们

我需要一个 bash 函数来接受可变数量的参数。这些参数是其他命令,如ls /rootecho HIgit clone http:// ....rm。该函数按顺序执行命令

该函数必须接受以下参数:

myfun <arbitrary set of commands>

请注意,每个命令本身可能有一组任意的参数。

myfun echo H ls /root git clone http://.... /home/myh/git/x1 

myfun 应该按如下方式执行

echo H
ls /root
git clone http://.... /home/myh/git/x1

传递参数的方式myfun可以改变。有没有办法实现所需的行为?

答案1

你可以有点这样做,但是,Michal Przybylowicz 建议,你不应该。如果你知道如果你想这样做,你可以跳过;否则,请考虑这些替代方案。

  • 如果您的目标是在一行中发出多个相继运行的命令,请用 将它们分隔开;
  • 如果您希望它们同时运行,请用 . 将它们分开&。这样,除了最后一个之外,其他所有任务都会在后台运行。如果您希望最后一个任务在后台运行,请在&其后面也加上 。
  • 如果您希望它们一个接一个地运行,但当其中一个失败时停止,请用&&而不是将它们分开;
  • 如果您希望能够将重定向应用于 while 命令块,请将它们括在 中{ }。开头的 后面需要一个空格{。结尾的}必须出现在新行上,或者在;其前面有一个。在同一行的 结尾后应用重定向}。例如,{ echo H; ls /root; } >out.txt
  • 如果你希望函数将其参数作为命令运行,原因是你想这样做其他有参数的东西,那么这个可能是合理的,但你应该考虑其他选择。如果你想跟踪它们,并且命令是交互输入的,那么你可能能够使用 shell 自己的历史记录功能;请参阅help historyhelp fc。如果你想立即显示将要运行的命令以及运行它们,请使用set -x;请参阅help set了解详情。

您通常不应该编写一个将其每个参数作为完整命令运行的函数,原因是使用这样的函数会很麻烦且容易出错,因为您必须引用由多个单词组成的每个参数(即,将一个或多个参数传递给命令)。这似乎并不那么糟糕……直到您意识到您的某些参数本身可能需要引用,在这种情况下您也必须引用引号。这是可行的,但远非理想。

作为问题的具体示例,请考虑您建议运行的可以调用函数的命令:

myfun echo H ls /root git clone http://.... /home/myh/git/x1 

这行不通。怎么myfun知道一个命令在哪里结束,下一个命令在哪里开始?


如果你真的想要实现这一点,一个合理的方法是使用eval内置函数(参见help eval)。您可以随意命名该函数,不必将其命名为eval_all

eval_all() { for cmd; do eval "$cmd"; done; }

for cmd效果与 相同for cmd in "$@"。使用您喜欢的变量名称cmd;只需记住进行相应更改即可$cmd。如果您想避免写入cmd函数外使用的变量:

eval_all() { local cmd; for cmd; do eval "$cmd"; done; }

无论您决定如何编写此函数,如果您想使用它来运行命令echo Hls,您可以像这样调用它:

eval_all 'echo H' ls

但你已经可以这样做了,这样更好:

echo H; ls

如果您还希望它运行命令touch 'honest $$$$ ideas.txt',您可以这样调用它:

eval_all 'echo H' ls 'touch '\''honest $$$$ ideas.txt'\'

还有其他方法可以引用单引号。没有一种方式特别漂亮。没有一种方式比以下方式更好:

echo H; ls; touch 'honest $$$$ ideas.txt'

相关内容