3

我正在编写一个应该对用户“透明”的 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

4 回答 4

5

你真的需要第二部分,用错误消息替换命令的输出吗?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更习惯地写为if <command>; then.
  • 引用可确保正确处理特殊字符和空格。
于 2012-10-04T14:32:50.250 回答
1

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

 echo "Error: command not found" >&2

我不确定它是否是第 1 条规则,但它肯定属于前 10 名,而且它可能是最常被违反的规则: Error messages belong on stderr. 在标准输出上打印错误消息的程序已损坏。

于 2012-10-04T16:48:45.027 回答
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

将输出 123&1

于 2018-06-29T15:01:54.567 回答
-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
于 2012-10-04T14:48:35.077 回答