仅当命令失败时redirectstdout?

我正在写一个应该对用户“透明”的bash脚本。 它从用户处读取命令并拦截它们,只允许其中一些命令由bash执行,具体取决于某些标准。 它(基本上)是这样工作的:

while true; do read COMMAND can_be_done $COMMAND if [ $? == 0 ]; then eval $COMMAND if [ $? != 0 ]; then echo "Error: command not found" fi fi done 

问题是,当命令失败的时候,你也可以把东西打印到控制台上。 但是,如果我把结果保存在一个variables中,只有在不失败时才打印出来,如下所示:

 RESULT=$(eval $COMMAND) 

然后还有另一个问题:特殊的格式会丢失(例如,“ls –color”不再显示颜色)

我的问题是:如果成功,有没有办法让打印到STDOUT的命令,但如果失败了/ dev / null?

你真的需要第二部分,用错误信息替换命令的输出吗? Linux命令打印自己的错误消息,这不一定是“找不到命令”。 你会隐藏真正的错误(权限被拒绝,文件未找到,内存不足,段错误等),通常不正确的错误信息(命令未找到)。

如果你删除这个检查,你可以简化这个循环:

 while true; do read -e COMMAND if can_be_done "$COMMAND"; then eval "$COMMAND" fi done 
  • read -e使用readline来获取命令,使提示更像shell(例如↑ ↓对于历史,例如)。
  • command; if [ $? == 0 ]; then command; if [ $? == 0 ]; then更习惯性地写成, if <command>; then if <command>; then
  • 引用确保特殊字符和空白处理正确。

我会强烈地争辩说,你不应该这样做。 如果您不想看到输出,请将其重定向到/dev/null 。 如果您确实想要查看错误,请不要重定向stderr。 如果您使用的程序在stdout而不是stderr上显示错误消息,请修复程序! 错误消息属于stderr。 请注意,这意味着您的程序已损坏,因为它应该是:

  echo "Error: command not found" >&2 

我不确定它是否是规则编号1,但它肯定属于前10位,并且可能是最常违反的规则: Error messages belong on stderr 。 在stdout上打印错误消息的程序被破坏。

假设这个命令运行起来不是很贵,你可以这样做:

  test `ls /mooo 2>/dev/null` || echo moo not found 

只有当命令以0结束时,测试才会返回true,在这种情况下,ls是命令。 你可以把它放在一个if语句中,像这样:

 if [ `ls /moo 2>/dev/null` ];then echo moo is a folder fi