如何在Bash脚本中仅将最终结果通过管道输出?
搞定Bash脚本的管道输出问题:只让结果走管道
咱们先理清楚你遇到的核心问题:为啥直接把脚本丢进管道,所有echo输出都被处理了?然后再一步步说正确的解法,以及你用>&0的写法存在哪些问题。
为啥直接管道脚本不符合预期?
当你执行./try.sh | rev时,脚本里所有写到stdout(标准输出,文件描述符1)的内容,都会被管道后面的rev捕获处理。你之前的脚本里,echo "hi"和echo $varname都默认输出到stdout,所以自然全部被反转了——但你想要的是提示信息直接显示给用户,只有最终输入的内容走管道被处理。
标准且可靠的解法:把提示信息丢去stderr
Unix/Linux的终端流设计里,除了stdout,还有个stderr(标准错误,文件描述符2):它默认直接输出到终端,不会被管道、重定向捕获,专门用来放提示、错误这类不需要后续处理的信息。
所以你只需要把提示信息重定向到stderr就行,脚本写法如下:
#!/bin/bash # 把提示信息输出到stderr,不参与管道处理 echo "hi" >&2 read varname # 最终结果输出到stdout,会被管道捕获处理 echo "$varname"
现在执行./try.sh | rev,echo "hi"会直接显示在终端让你看到,你输入的内容则会被rev反转后输出,完全符合你的预期。
关于你用>&0的写法:别这么干!
你尝试的echo test >&0是把输出重定向到stdin(标准输入,文件描述符0),这绝对不是惯用解法,而且有一堆坑:
- 行为不可控:如果脚本的stdin被重定向了(比如
./try.sh < input.txt),那>&0的输出会被写到input.txt里,而不是终端,完全达不到提示用户输入的目的。 - 违背设计原则:stdin是用来读取输入的,不是用来输出内容的,这种写法会让其他维护脚本的人一脸懵,不符合Unix的IO流规范。
- 兼容性差:虽然bash能正常执行,但在dash这类轻量shell里可能直接报错,移植性极差。
总结一下:把提示信息输出到stderr是最稳妥、最符合规范的做法,完全能解决你的需求。
内容的提问来源于stack exchange,提问作者somina
相关产品推荐
相关产品推荐

