如何逐行(而不是作为脚本)运行多个交互式命令行?

时间:2018-08-05 14:40:15

标签: bash

我有多个要在bash中运行的命令。因为这些cmd本质上是交互式的,所以我不能将它们放在脚本中并作为脚本运行(./cmds不适用)

但是我想逐行将它们放在文件(如文本文件)中,并作为命令行逐行运行(而不是脚本):

$ bash < my_cmds_as_text_line_by_line.txt


#my_cmds_as_text_line_by_line.txt
cmd1
cmd2
cmd3

问题 以上执行与:

bash -c cmd1
bash -c cmd2
bash -c cmd3

2 个答案:

答案 0 :(得分:1)

您的问题的答案是“不,两者不相同”。

如果您运行:

bash < my_cmds_as_text_line_by_line.txt

其中提到的文件包含:

cmd1
cmd2
cmd3

与以下不同:

bash -c "cmd1"
bash -c "cmd2"
bash -c "cmd3"

因为每行现在都在自己的全新bash shell中执行,而不是可能受先前命令影响的行,

  • 更改目录
  • 更改了环境变量

想象cmd1cd /usr,在第二种方案中,它将目录更改为/usr,然后退出bash shell,并开始一个新的shell-一起在其他地方。 / p>

答案 1 :(得分:1)

除了Mark Setchell指出的差异(使用bash -c运行单独的命令而不保持环境变化)之外,还有另一个重要的差异:使用bash <file从文件中重定向标准输入(这就是{{ 1}}),这意味着(几乎)所有输入(不仅仅是命令)都是从文件而不是从终端读取的。例如,假设您将其作为文件:

<

如果使用read -p "Enter some text: " input echo "You entered: $input" echo "No, really, you entered: $input" 运行这些命令,则bash <file命令将从文件而不是终端读取:

read

如果不清楚此处发生的情况,我将详细解释。 $ bash <script.sh No, really, you entered: echo "You entered: $input" 以脚本文件作为输入。它读取第一行,并将其作为命令执行。那是bash命令,因此它从文件中读取一行 (获取文件的第二行),并将其分配给变量read。然后,它读取下一行(第三行)并再次将其作为命令执行。

另一方面,让我们与input逐行尝试:

bash -c

这里发生的是马克所描述的。第一条命令已从终端成功读取,并将输入分配给变量$ bash -c 'read -p "Enter some text: " input' Enter some text: Hey, look, it's actually letting me enter something here! $ bash -c 'echo "You entered: $input"' You entered: $ bash -c 'echo "No, really, you entered: $input"' No, really, you entered: 。但是第二和第三个命令具有新环境,没有设置该变量,因此将其打印为空白。

这给我带来了一种更好的方式来运行文件中的命令:使用input运行(注意缺少bash file)。这告诉bash打开文件并从中读取命令,但没有其他内容。标准输入不受影响,因此脚本中的交互式命令可以像通常一样从终端读取:

<

但是还有一种更好的方法:添加一个shebang行,使脚本可执行,然后使用$ bash script.sh Enter some text: Hey, look, it's actually letting me enter something here! You entered: Hey, look, it's actually letting me enter something here! No, really, you entered: Hey, look, it's actually letting me enter something here! 运行它。这样一来,人们就可以运行脚本而不必担心该脚本使用哪种脚本语言。这被认为是运行脚本的正常方法,这是有原因的:它通常比其他方法要好。