我试图对运行交互式 BASH 脚本的用户隐藏所有 stderr,但将错误保留在日志文件中。然而,简单的 stderr 重定向出乎意料地隐藏了一些应该转到的 BASH 输出标准输出反而。在两个系统上尝试过这一点并得到相同的结果(一个有GNU bash,版本 4.1.2(1)-发布 (x86_64-redhat-linux-gnu)另一个是在 MacOS X 上)。
我一直怀疑这可能是由于exec
更换外壳引起的......但是另一个内置的(times
) 按预期工作并输出到标准输出!
一个例子:
#!/bin/bash
exec 2>>file_log
echo This will be printed to stdout, as expected
ls ThereIsNoSuchFileOnEarth # this will go to “file_log”, as expected
read –p 'User would never see this prompt and it would go to file_log. Totally unexpected.' –r -e test
species=”Daleks Raxacoricofallapatorians Judoon”
select enemy in $species;
do
# …code omitted as the user would never see the list. It would go into file_log again!
done
答案1
提示来自read
和select
应该是转到标准错误,因为它们可能是用户交互的提示,而不是实际的提示输出。这允许您运行tool.sh > tool.out
并仍然使用read
并向select
用户收集信息,而不会“污染”实际输出。
标准输出是一个程序的典型输出,理想情况下它可以通过管道传输到另一个程序的标准输入,既不麻烦,也不混乱。
这也是为什么curl
,例如,在标准错误而不是标准输出上显示其下载进度;您可以并且仅显示curl http://www.example.com/path/to/file > file
的内容(因此重定向到,而信息数据使用标准错误显示。file
file
答案2
如果您使用exec
重定向整个 shell 的 stderr,这会影响整个 shell。
您要么不能使用exec
重定向整个 stderr,要么需要调用类似以下内容的内容:
read .... 2> /dev/tty
让相关的内置函数为 stderr 创建可读的输出。