这按预期工作
$> cat ./readfromstdin.sh
echo reading
cat /dev/stdin
$> echo hello | ./readfromstdin.sh
reading
hello
我正在尝试在没有临时文件的情况下实现类似的目标。我的第一次尝试是
echo hello | (echo cat /dev/stdin|sh)
这不起作用。使用heredoc它也不起作用(尽管我不确定正确的语法是什么:
echo hello | (cat << EOF | sh
cat /dev/stdin
EOF)
pipe cmdsubst pipe heredoc>
是否可以使用通过管道传输到 shell 的脚本从 stdin 读取数据?
答案1
您可以通过管道到子 shell 来相对轻松地完成您所描述的操作:
$ echo hello | ( echo reading; cat /dev/stdin )
reading
hello
我承认我真的无法想象这个的任何用例。为什么不直接做:
$ echo hello | ( echo reading; read var; echo "$var")
reading
hello
这样您就可以将标准输入内容保存为变量,并可以在闲暇时操作它们。
答案2
$ echo 'world' | { echo 'hello'; cat }
hello
world
无需显式给出,/dev/stdin
因为cat
如果cat
没有给出其他操作数,则默认情况下会进行操作。
在您自己的代码中,看起来好像您想传递一个命令而不是要输出的字符串。sh
无论如何,这就是我解释代码中的存在的方式。但我不完全确定你需要这个。
您这样做时遇到的问题是由于将脚本提供给sh
其标准输入造成的。因此,标准输入将保留用于命令,因此通过管道将字符串输入其中将不起作用。
答案3
您的意思是您想从子 shell 访问 stdin,该子 shell 已经通过 stdin 传递了命令,该命令引用了从父进程传递的 stdin ?
这真是拗口——你的意思是这样的吗:
$ cat ~/.tmp/test.sh
#!/bin/bash
set -eu
echo i am stdin from pipe | {
echo '0</dev/fd/100 cat -' | sh -x
} 100<&0
$ ~/.tmp/test.sh
+ cat -
i am stdin from pipe
echo i am stdin from pipe
重定向到fd100<&0
以免丢失引用'0</dev/fd/100 cat -'
作为字符串传递到标准输入,并对其sh -x
进行评估和执行- 标准输入
/dev/fd/100
引用被重定向/dev/stdin
到进程cat -
,该进程将字符串写入标准输出i am stdin from pipe
需要明确的是,永远不要这样做^^。