根据变量的开头,我的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
我的剧本出了什么问题? 谢谢你的帮助!
答案 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是在空格上分离你的字符串而且有一些副作用。