Linux bash if - elif不按预期工作

时间:2017-01-04 12:21:01

标签: linux bash

根据变量的开头,我的Bash-Script必须做一些不同的事情。 当我运行以下脚本时:

#!/bin/bash

line="__B something"

if [ -n $(echo "$line" | grep "^__A") ]; then
   echo "Line __A"
elif [ -n $(echo "$line" | grep "^__B") ]; then
   echo "Line __B"
elif [ -n $(echo "$line" | grep "^__C") ]; then
   echo "Line __C"
elif [ -n $(echo "$line" | grep "^__D") ]; then
   echo "Line __D"
elif [ -n $(echo "$line" | grep "^__E") ]; then
   echo "Line __E"
elif [ $(echo "$line" | grep "^__F") ]; then
   echo -n "Line __F"
else
   echo "something other"
fi

Bash无法识别字符串以__B。开始:

输出是:

Line __A

我的剧本出了什么问题? 谢谢你的帮助!

2 个答案:

答案 0 :(得分:2)

如果使用xtrace选项运行脚本,则可以看到发生的情况:

bash -x your-script
+ line='__B something'
++ echo '__B something'
++ grep '^__A'
+ '[' -n ']'
+ echo 'Line __A'
Line __A

因为您使用了旧的test 内置(也称为[),所以扩展已完成但除了-n之外无法进行任何测试。使用[[ 关键字会正确引用内容:

bash -x your-script
+ line='__B something'
++ echo '__B something'
++ grep '^__A'
+ [[ -n '' ]]
++ echo '__B something'
++ grep '^__B'
+ [[ -n __B something ]]
+ echo 'Line __B'
Line __B

但是,使用外部程序grep是一种浪费。 bash的最新版本内置了正则表达式(RE)(使用绑定运算符=~),但在这种情况下您不需要RE,简单的通道将执行:

#!/bin/bash

line="__B something"

if [[ $line == __A* ]]; then
   echo "Line __A"
elif [[ $line == __B* ]]; then
   echo "Line __B"
elif [[ $line == __C* ]]; then
   echo "Line __C"
elif [[ $line == __D* ]]; then
   echo "Line __D"
elif [[ $line == __E* ]]; then
   echo "Line __E"
elif [[ $line == __F* ]]; then
   echo -n "Line __F"
else
   echo "something other"
fi

答案 1 :(得分:1)

我认为这与条件限制在bash中使用[[[之间差异的微妙之处有关。

你可以在任何地方使用[[]](似乎有用),例如。

if [[ -n $(echo "$line" | grep "^__A") ]]; then
   echo "Line __A"

或者您可以像这样引用子shell

if [ -n "$(echo '$line' | grep '^__A')" ]; then
   echo "Line __A"
  

[[减少意外,通常使用起来更安全。但事实并非如此   便携式 - Posix没有指定它的功能,也没有指定一些shell   支持它(在bash旁边,我听说ksh也支持它)。例如,   你可以做到

     

[[ -e $b ]]

     

测试文件是否存在。但是对于[,您必须引用$b,   因为它会拆分参数并扩展"a*"之类的内容(其中[[   从字面上看它。这也与[如何成为外部因素有关   程序并通常像其他人一样接收它的论点   程序(虽然它也可以是内置的,但它仍然没有   这种特殊处理)。

根据this在stackoverflow上的回答。所以在你的情况下,很可能bash是在空格上分离你的字符串而且有一些副作用。