我对此感到有点困惑
$ bash <<EOF
read -p 'This will not work' input
EOF
,因为
$ cat script
read -p 'This will work fine' input
$ bash script
This will work fine
区别是什么?它似乎是一种标准行为,因为ash
的行为方式完全相同。
根据目前为止提供的答案,我怀疑(然后确认)以下工作。我认为这实际上是我一直想做的事情,但<()
语法总是存在的。
$ bash <( cat <<EOF
read -p 'This works' input
EOF
)
答案 0 :(得分:2)
每个进程不能同时有多个stdin
,因此作为bash
输入传递的here文档不能包含read -p
。
使用bash script
,正在运行的script
是Bash shell的子进程,并且stdin
与read
没有并发,因此它将按预期工作。
答案 1 :(得分:2)
在这两种情况下,read
命令都会从执行它的bash
进程继承其标准输入。
在第一个示例中,这意味着实际包含 read
命令的here文档。根据文档bash
已经读取了多少(通常是全部),read
没有任何内容可供阅读,因此它以非零退出状态退出。
在第二个示例中,bash
在不同的文件描述符上打开指定文件。 read
仍继承bash
进程的标准输入,但这次bash
根本没有从中读取,因此read
命令可以获得下一个线。这里的标准输入是终端,因此read
会阻塞,直到用户输入一行。
答案 2 :(得分:1)
由于read
是一个内置的bash,它会从bash
继承stdin,如上所述。在第一种情况下,bash
将此处的文档作为标准输入(或更专业的文档描述符0),并且read
没有任何内容可供阅读。
read
仅从stdin(fd0
)读取,而在第二种情况下,bash
打开另一个文件描述符而不是stdin从script
读取脚本,这样做 NOT 与传递给read
的标准输入的冲突,以便read
可以按预期工作。
你可以试试这个来测试。
$ bash << EOF ls -l /proc/$$/fd EOF
和
$ cat script.sh ls -l /proc/$$/fd $ bash script.sh如果比较样本中的输出,差异很明显。
答案 3 :(得分:0)
最简单的解决方案是将交互式命令写入一个临时文件,然后获取该临时文件:
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'"