仅在命令失败时重定向stdout?

时间:2012-10-04 14:17:03

标签: linux bash shell

我正在写一个应该是"透明的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

问题是,当命令失败时,您还会将内容打印到控制台。但是,如果我将结果保存在一个变量中,并且只在它没有失败时打印它,就像这样:

RESULT=$(eval $COMMAND)

然后又出现了另一个问题:特殊格式丢失了(例如," ls --color"不再显示颜色)

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

4 个答案:

答案 0 :(得分:5)

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

如果删除该检查,则可以将循环简化为以下内容:

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

答案 1 :(得分:1)

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

 echo "Error: command not found" >&2

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

答案 2 :(得分:0)

if false > /dev/null;then echo 1; else echo 2; fi 2> /dev/null

会输出2

if true > /dev/null;then echo 1; else echo 2; fi 2> /dev/null

会输出1

删除> /dev/null以将命令也打印到标准输出

例如 if echo 123;then echo 1; else echo 2; fi 2> /dev/null

将输出 1231

答案 3 :(得分:-1)

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

   test `ls /mooo 2>/dev/null` || echo moo not found
只有当命令以0退出时,

test才会返回true,在这种情况下,ls是命令。你可以将它放在if语句中,就像这样:

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