Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么在使用heredoc作为shell的输入时stdin是关闭的_Shell_Heredoc - Fatal编程技术网

为什么在使用heredoc作为shell的输入时stdin是关闭的

为什么在使用heredoc作为shell的输入时stdin是关闭的,shell,heredoc,Shell,Heredoc,我对此有点困惑 $ bash <<EOF read -p 'This will not work' input EOF 有什么区别?这似乎是一种标准行为,因为ash的行为方式完全相同 根据到目前为止提供的答案,我怀疑(然后证实)以下方法有效。我认为这实际上是我一直想要做的,但是每个进程不能同时有多个stdin,因此作为输入传递给bash的here文档不能包含read-p 对于bash脚本,运行的script是bash shell的一个子进程,并且没有并发的stdin到read

我对此有点困惑

$ bash <<EOF
  read -p 'This will not work' input
EOF
有什么区别?这似乎是一种标准行为,因为
ash
的行为方式完全相同



根据到目前为止提供的答案,我怀疑(然后证实)以下方法有效。我认为这实际上是我一直想要做的,但是
每个进程不能同时有多个
stdin
,因此作为输入传递给
bash
的here文档不能包含
read-p


对于
bash脚本
,运行的
script
是bash shell的一个子进程,并且没有并发的
stdin
read
,因此它将按预期工作。

read
命令从执行它的
bash
进程继承其标准输入

在第一个示例中,这意味着此处的文档实际上包含
read
命令。根据文档
bash
已经读取了多少(通常是全部),没有剩余内容可供
read
读取,因此它以非零退出状态退出


在第二个示例中,
bash
在不同的文件描述符上打开命名文件
read
仍然从
bash
进程继承其标准输入,但这次
bash
根本没有从中读取,因此
read
命令获得下一行可用的内容。这里的标准输入是终端,所以
read
阻塞直到用户输入一行。

因为
read
是bash内置的,它继承了上面提到的
bash
的stdin。在第一种情况下,
bash
将一个here文档作为stdin(或者更专业地说,是文件描述符0),并且没有任何内容可供
读取。
read
仅从stdin(
fd0
)读取,而在第二种情况下,
bash
打开另一个文件描述符而不是stdin从
script
读取脚本,这与传递给
read
的stdin不冲突,因此
read
可以按预期工作。

您可以尝试此测试。

$ bash << EOF ls -l /proc/$$/fd EOF
$bash最简单的解决方案是将交互命令写入一个临时文件,然后为临时文件提供源代码:

cat <<'_EOF_' >/tmp/$$.sh
read -p 'This is an interactive command, please enter a string: ' STRING
_EOF_
# Command in temporary file get executed here
source /tmp/$$.sh
echo "STRING= '$STRING'"
cat
$ bash << EOF
ls -l /proc/$$/fd
EOF
$ cat script.sh
ls -l /proc/$$/fd
$ bash script.sh
cat <<'_EOF_' >/tmp/$$.sh
read -p 'This is an interactive command, please enter a string: ' STRING
_EOF_
# Command in temporary file get executed here
source /tmp/$$.sh
echo "STRING= '$STRING'"