当输出通过管道传输时,如何提示用户输入?
> (echo -n 'input data: '; read TEST; export TEST) | echo "done: ${TEST}"
这不会显示“输入数据”提示,也不会从标准输入读取任何内容,而是只显示:
done:
答案1
foo | bar
foo
同时运行bar
。您的代码显示出来是done:
因为 finalecho
不会读取其 stdin,也不会等待通过其 stdin 管道传输的任何内容。它会立即完成其工作。
此外,${TEST}
after与您设置的 before|
变量无关。构建管道时,Bash 在单独的子 shell 中运行每个命令(最后一个命令可能会或可能不会在主 shell 的上下文中执行)。read
|
我认为这就是你想要的:
echo -n 'input data: '; read TEST
echo "done: ${TEST}"
(在 Bash 中read -p 'input data: ' TEST
也可以工作)。
这里无需将任何东西通过管道传输到任何东西。
一般来说,如果你需要从管道内(我的意思是从真正需要的管道内)与用户交互,这/dev/tty
可能会很有用。人工示例:
echo foo | ( read -p 'i: ' var </dev/tty; echo "d: $var" >/dev/tty; cat ) | nl
这里read
不是从第一个 读取echo
,而是从 读取/dev/tty
。这两个read
和 第二个都不echo
打印到nl
:read -p
默认情况下将其提示打印到 stderr,因为我们重定向了,echo
所以打印到/dev/tty
。实际上,数据(foo
+newline)从 到 ,echo
好像cat
那里nl
没有其他东西一样。
这可能看起来像一个诡计,但它是一个合法的用例。例如参见ssh
当 stdout 和 stderr 都被重定向时,如何/为什么输出到 tty?和我的答案在那里。