有没有一种方法可以在bash中有效地做到这一点:
/my/bash/script < echo 'This string will be sent to stdin.'
我知道我可以从echo输出这样的管道:
echo 'This string will be piped to stdin.' | /my/bash/script
有没有一种方法可以在bash中有效地做到这一点:
/my/bash/script < echo 'This string will be sent to stdin.'
我知道我可以从echo输出这样的管道:
echo 'This string will be piped to stdin.' | /my/bash/script
当前回答
你也可以像这样使用read
echo "enter your name"
read name
echo $name
其他回答
您可以使用单行heredoc
cat <<< "This is coming from the stdin"
以上同
cat <<EOF
This is coming from the stdin
EOF
或者您可以重定向来自命令的输出,例如
diff <(ls /bin) <(ls /usr/bin)
或者你可以读成
while read line
do
echo =$line=
done < some_file
或者简单地
echo something | read param
cat | /my/bash/script
允许在程序中输入多行,而输入不会被保存在历史记录中,也不会在ps中可见。以换行符结束,然后按Ctrl + D结束cat。
你也可以像这样使用read
echo "enter your name"
read name
echo $name
解决方案
你想(1)在一个进程中创建stdout输出(如echo '…'),(2)将输出重定向到另一个进程的stdin输入,但(3)不使用bash管道机制。下面是一个同时满足这三个条件的解决方案:
/my/bash/script < <(echo 'This string will be sent to stdin.')
<是stdin的正常输入重定向。<(…)是bash进程替换。粗略地说,它用替换命令的输出创建了一个/dev/fd/…文件,并将该文件名传递给<(…),例如在脚本< /dev/fd/123中详情请参见此回答。
与其他方案的比较
发送给stdin脚本<<< 'string'的一行heredoc只允许发送静态字符串,而不是其他命令的输出。 单独的进程替换,例如在diff <(ls /bin) <(ls /usr/bin)中,不会向stdin发送任何内容。相反,流程输出被保存到一个文件中,其路径作为命令行参数传递。对于上面的例子,这相当于diff /dev/fd/10 /dev/fd/11,一个命令,其中diff没有从stdin接收输入。
用例
我喜欢这一点,与管道机制不同,< <(…)机制允许将命令放在前面,所有输入放在后面,这是命令行选项输入的标准。
然而,除了命令行美学之外,还有一些情况下不能使用管道机制。例如,当某个命令必须作为另一个命令的参数提供时,例如本例中的sshpass。
别名可以或不能处理管道stdin… 这里我们创建了3行输出
$ echo -e "line 1\nline 2\nline 3"
line 1
line 2
line 3
然后,我们将输出通过管道输送到sed命令的stdin,以将它们全部打开 一行
$ echo -e "line 1\nline 2\nline 3" | sed -e ":a;N;\$!ba ;s?\n? ?g"
line 1 line 2 line 3
如果我们定义同一个sed命令的别名
$ alias oline='sed -e ":a;N;\$!ba ;s?\n? ?g"'
我们可以通过管道将输出输出到别名的标准输入中,它会正常工作 完全一样
$ echo -e "line 1\nline 2\nline 3" | oline
line 1 line 2 line 3
当我们试图将别名定义为函数时,问题就出现了
$ alias oline='function _oline(){ sed -e ":a;N;\$!ba ;s?\n? ?g";}_oline'
将别名定义为函数将打破管道
$ echo -e "line 1\nline 2\nline 3" | oline
>