2012-10-04 25 views
3

我在写一个应该对用户“透明”的bash脚本。它从用户那里读取命令并拦截它们,只允许其中一些命令由bash执行,具体取决于某些标准。它(基本上)是这样工作的:仅当命令失败时才重定向stdout?

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 “不再显示颜色)

我的问题是:如果成功,是否有一种方法可以将命令打印到标准输出,但如果失败则会将其打印到/ dev/null?

+0

颜色不会丢失对我来说。 RESULT = $(eval ls --color); echo“$ RESULT” – dogbane

+0

@dogbane'ls --color'表示'ls --color = always'。通常'ls'被别名为'ls --color = auto'或'ls --color = tty',即它只在stdout是终端('isatty')时才打印颜色代码。 –

+0

我刚刚意识到,你是对的!但由于某些原因,“ls --color = auto”(这是用于ls的别名)。我删除了“= auto”,现在用这种方法显示颜色。 –

回答

5

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

如果删除检查,可以简化这样循环的东西:

while true; do 
    read -e COMMAND 
    if can_be_done "$COMMAND"; then 
     eval "$COMMAND" 
    fi 
done 
  • read -e使用的readline获取命令,使提示了很多壳状(&箭头更;例如,↓)。
  • command; if [ $? == 0 ]; then更习惯写成if <command>; then
  • 引用确保特殊字符和空白处理正确。
+0

感谢您的建议。正如你可能知道的,我对bash脚本非常陌生! –

+0

或'can_be_done'$ COMMAND“&& $ COMMAND' – punund

-1

假设该命令不运行,你可以做到这一点非常昂贵:

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

测试将返回true只有在命令退出时0,在这种情况下,LS是命令。你可以在if语句中已经把这个太像这样:

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

'if ls;然后'检查ls的退出代码。 ''如果['ls']''等于''if [-n'ls']'';它检查ls没有输出任何东西。 –

+0

我有点急躁的回答。这是完全错误的。 –

1

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

echo "Error: command not found" >&2 

我不知道这是否是第一条规则,但它肯定是属于前10名,这可能是最经常违反规则:Error messages belong on stderr。在stdout上打印错误消息的程序已损坏。