Linux-bash-if-elif-don';I don’我没有按预期工作
根据变量的开头,我的Bash脚本必须做一些不同的事情。 当我运行以下脚本时:Linux-bash-if-elif-don';I don’我没有按预期工作,linux,bash,Linux,Bash,根据变量的开头,我的Bash脚本必须做一些不同的事情。 当我运行以下脚本时: #!/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") ]; t
#!/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
我的剧本怎么了?
谢谢你的帮助 我认为这与在bash if条件中使用
[[
和[
之间的细微差别有关
您可以在任何地方使用[[
和]
(似乎有效),例如
或者你可以这样引用subshell
if [ -n "$(echo '$line' | grep '^__A')" ]; then
echo "Line __A"
[[
的惊喜更少,使用起来更安全。但事实并非如此
portable-Posix没有指定它的功能,只指定了一些shell
支持它(除了bash之外,我听说ksh也支持它),
你能行
[[-e$b]]
要测试文件是否存在。但是使用[
,您必须引用$b
,
因为它拆分参数并展开类似于“a*”
(其中[[
这也与[
如何成为外部代码有关
程序,并像其他程序一样正常地接收其参数
程序(虽然它也可以是一个内置的,但它仍然没有
这是一种特殊的处理方法)
根据这里关于stackoverflow的回答。所以在您的例子中,bash很可能是在一个空格中分隔字符串,这有一些副作用。我认为这与在bash if条件中使用
[[
和[
之间的细微差别有关
您可以在任何地方使用[[
和]
(似乎有效),例如
或者你可以这样引用subshell
if [ -n "$(echo '$line' | grep '^__A')" ]; then
echo "Line __A"
[[
的惊喜更少,使用起来更安全。但事实并非如此
portable-Posix没有指定它的功能,只指定了一些shell
支持它(除了bash之外,我听说ksh也支持它),
你能行
[[-e$b]]
要测试文件是否存在。但是使用[
,您必须引用$b
,
因为它拆分参数并展开类似于“a*”
(其中[[
这也与[
如何成为外部代码有关
程序,并像其他程序一样正常地接收其参数
程序(虽然它也可以是一个内置的,但它仍然没有
这是一种特殊的处理方法)
根据这里关于stackoverflow的回答。因此,在您的情况下,bash很可能在空格中分隔字符串,这会产生一些副作用。如果您使用
xtrace
选项运行脚本,您可以看到发生了什么:
bash -x your-script
+ line='__B something'
++ echo '__B something'
++ grep '^__A'
+ '[' -n ']'
+ echo 'Line __A'
Line __A
因为您使用了旧的测试
内置(也称为[
),所以扩展已完成,但除了-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
内置了正则表达式(REs)(使用绑定操作符=~
),但您不需要REs。在这种情况下,简单的全局搜索可以:
#!/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
如果使用
xtrace
选项运行脚本,则可以看到发生了什么:
bash -x your-script
+ line='__B something'
++ echo '__B something'
++ grep '^__A'
+ '[' -n ']'
+ echo 'Line __A'
Line __A
因为您使用了旧的测试
内置(也称为[
),所以扩展已完成,但除了-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
内置了正则表达式(REs)(使用绑定操作符=~
),但您不需要REs。在这种情况下,简单的全局搜索可以:
#!/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
看起来你错放了最后一个
-n
使用更多的引号!如果[-n”$(echo…);那么。引用参数扩展!(但你的设计非常糟糕)。@gniourf\u gniourf:如果你尝试双引号引用整个echo | grep
命令(不仅仅是你显示的剪报)你会发现它并不是那么简单,特别是考虑到$line
@cdarke中的嵌入空间:$line
中的嵌入空间如何?@OP:这将是case
的典型用法!case$line in(u a*)echo“line”;(u B*)echo“line”;(*)echo“line”;(*)echo“other”;esac
。看起来你错放了最后一个-n
使用了更多的引号!如果[-n$(echo…);那么。引用参数扩展!(但是你的设计很糟糕)。@gniourf\u gniourf:如果你试图双引号引用整个echo | grep
命令(不仅仅是你显示的snip)你会发现它并不那么简单,特别是考虑到$line
@cdarke中的嵌入空间:$line
中的嵌入空间如何?@OP:这将是案例的典型用法!案例$line in(u a*)echo“line”;(u B*)echo“line”;(*)echo“line”;(*)echo“line”;(*)echo“other”;
。