Bash:在脚本中执行多命令行字符串

Bash: execute a multi-command line string in a script

在一个文件中,有一些像这样的多命令行:

cd /home/user; ls

在 bash 脚本中,我想执行这些命令,并在最后一个命令中添加一些参数。例如:

cd /home/user; ls   -l *.png

我认为做这样的事情就足够了:

#!/bin/bash
commandLine="$(cat theFileWithCommandInside)   -l *.png"
$commandLine
exit 0

但是它说:

/home/user;: No such file or directory

换句话说,“;”字符不再意味着 "end of the command": shell 正在尝试在主文件夹中找到一个名为 "user;" 的目录...

我尝试替换“;”用"&&",结果是一样的

关键是:eval

这里固定脚本(看第三行):

#!/bin/bash
commandLine="$(cat theFileWithCommandInside)   -l *.png"
eval $commandLine
exit 0

为什么不在脚本中执行命令本身,而是 "importing" 它们?

#!/bin/bash
cd /home/user; ls -l *.png
exit 0

将命令包装成一个函数:

function doLS() {
    cd user; ls $@
}

$@ 扩展为传递给函数的所有参数。如果您(或代码片段作者)添加需要预定义参数数量的函数,您可能会发现位置参数 </code>、<code>、... 很有用。

作为主要脚本的维护者,您必须确保提供此类代码段的每个人都提供 "interface" 您的代码使用(即他们的代码定义了您的程序调用的函数,并且他们的函数处理您的程序传递的参数)。

使用 source. 将函数导入您的 运行ning shell:

#!/bin/bash
source theFileWithCommandInside
doLS -l *.png
exit 0

我想补充一些关于 ; 主题的想法:

In other words, the ";" character doesn't mean anymore "end of the command": The shell is trying to find a directory called "user;" in the home folder...

; 不像在 C 风格语言中那样用于终止语句。相反,它用于分隔应在 list 中按顺序执行的命令。在 subshell:

中执行两个命令的示例
( command1 ; command2 )

如果列表是 的一部分,则必须在 ;:

之后
{ command1 ; command2 ; }

在您的示例中,将不会执行标记化和通配符(替换 *)(如您所料),因此您的代码不会 运行 成功。

你的问题的重点是执行存储在字符串中的命令。有数千种方法可以间接执行。但最终,bash 必须参与。

那么为什么不显式调用 bash 来完成这项工作呢?

bash -c "$commandLine"

来自文档:

-c string

If the -c option is present, then commands are read from string. If there are arguments after the string, they are assigned to the positional parameters, starting with [=11=].

http://linux.die.net/man/1/bash

使用 <(...) 形式

sh <(sed 's/$/ *.png/' theFileWithCommandInside)