将命令传递给在 Linux 计算机上等待输入的脚本

将命令传递给在 Linux 计算机上等待输入的脚本

我正在尝试运行一个 shell 脚本,其中我将调用另一个脚本,第二个脚本等待提供一些命令。我已经使用 echo 来传递命令,但它不起作用。第二个脚本继续等待输入。

脚本1:

#!/bin/sh
set -x
sh script2.sh
echo ".open Simulation\n"
set +x

但这不会产生任何结果。它继续等待。

输出:

./script1.sh
+ sh script2
<Nothing appears here>

答案1

默认情况下,Linux 系统上的每个进程都有一个输入(stdin)和两个输出(stdout、stderr)。终端从键盘获取输入并将其发送到它们运行的​​ shell 的 stdin,并从进程中获取 stdout 和 stderr 并将其打印到屏幕。

当您在 shell 中(在终端中)运行命令时,它将自己的标准输入链接到进程的标准输入,因此您键入的任何键都会发送到该命令。它还将它们的 stdout 和 stderr 链接到它自己的(然后终端将其打印到屏幕上)。当您在脚本中运行命令时,也会发生同样的事情,stdin、stdout 和 stderr 链接到父进程的命令,这些最终传播到终端。

此外,脚本中的命令默认是阻塞的。只有当他们正在运行的命令完成后,他们才会执行下一个命令。

鉴于这些,让我们看看您的脚本(简化为感兴趣的两行):

sh script2.sh
echo ".open Simulation\n"

它的作用是运行 sh (运行 script2.sh)并将其标准输入附加到脚本的标准输入并阻止等待其结束。在第一个进程结束之前,第二行不会运行。

现在,您在 shell 中输入的任何内容.open Simulation\n都会发送到 sh,后者会将其发送到您的script2.sh.一旦(如果有的话)script2.sh完成,它将退出,并且您的主脚本将回显.open Simulation\n到 shell 并退出。

现在我们知道发生了什么事。我们该如何解决它?那么您可以覆盖 stdin、stdout 和 stderr 的默认附加到您想要的任何位置,包括文件或其他进程。为此,shell 必须拥有强大的实用程序、输入/输出重定向和命令管道。

I/O 重定向允许您将输入/输出重定向到您想要的任何文件解密,例如:

echo "contents of a file" > somefile.txt

这将通过将 echo 命令的 stdout 重定向到 来contents of a file写入。输入重定向的工作方式相同:somefile.txtsomefile.txt

cat < somefile.txt

将通过重定向 cats stdin 来读取文件的内容到屏幕上somefile.txt(请注意,这是一个人为的示例,大多数人只会cat somefile.txt导致 cat 本身读取 somefile.txt 而不是让 shell 执行此操作。)

接下来是命令管道,它们允许您将一个程序的标准输出连接到另一个程序的标准输入。这听起来像您想要的,将 echo 的输出发送到脚本的 stdin 中:

echo ".open Simulation" | sh script2.sh

现在,这对于简单输入来说效果很好,但是如果您有超过几行,则有一种更简单的方法;此处文档。例如,要将多行管道传输到脚本中,您可以

sh script2.sh <<EOD
.open Simulation
.do something
.end Simulation
EOD

这会将三行(不包括 EOD)发送到您的脚本,准备好您的脚本进行处理。如果您需要做任何更高级的事情,您也可以使用子命令重定向,这将允许您将子 shell 的输出重定向到您的程序中,这里每行之间有一个 sleep 1:

sh script2.sh <(
    echo ".open Simulation"
    sleep 1
    echo ".do something"
    sleep 1
    echo ".end Simulation"
)

在此示例中,您的脚本将.open Simulation立即看到,然后在一秒钟后它将在 stdin 关闭之前.do something再过一秒。.end Simulation

答案2

尝试

echo ".open Simulation" | sh script2.sh

因为在您的脚本中,您刚刚启动 script2.sh 并且它正在等待输入。使用管道将 echo 的输出发送到 script2.sh 的标准输入

抱歉,您不需要在 echo 中插入 '\n',因为它默认打印换行符。 (谢谢三哥)

相关内容