我想检查字符串是否以 “node” 开头,例如 “node001”。就像是
if [ $HOST == user* ]
then
echo yes
fi
如何正确执行?
我还需要结合表达式来检查 HOST 是 “user1” 还是以 “node” 开头
if [ [[ $HOST == user1 ]] -o [[ $HOST == node* ]] ];
then
echo yes
fi
> > > -bash: [: too many arguments
如何正确执行?
《高级 Bash 脚本指南》中的此代码段说:
# The == comparison operator behaves differently within a double-brackets
# test than within single brackets.
[[ $a == z* ]] # True if $a starts with a "z" (wildcard matching).
[[ $a == "z*" ]] # True if $a is equal to z* (literal matching).
所以你几乎正确了;您需要双括号,而不是单括号。
关于第二个问题,您可以这样写:
HOST=user1
if [[ $HOST == user1 ]] || [[ $HOST == node* ]] ;
then
echo yes1
fi
HOST=node001
if [[ $HOST == user1 ]] || [[ $HOST == node* ]] ;
then
echo yes2
fi
哪个会回声
yes1
yes2
Bash 的if
语法很难习惯(IMO)。
如果您使用的是最新版本的 Bash(v3 +),则建议使用 Bash regex 比较运算符=~
,例如,
if [[ "$HOST" =~ ^user.* ]]; then
echo "yes"
fi
要匹配正则表达式this or that
|
, 例如,
if [[ "$HOST" =~ ^user.*|^host1 ]]; then
echo "yes"
fi
注意 - 这是 “正确” 的正则表达式语法。
user*
表示r
use
和零个或多个出现,因此use
和userrrr
将匹配。user.*
表示user
和任何字符的零个或多个出现,因此user1
和userX
将匹配。^user.*
表示在 $ HOST 开头匹配模式user.*
如果您不熟悉正则表达式语法,请尝试参考此资源。
我始终尝试使用 POSIX sh
而不是使用 Bash 扩展,因为脚本编写的主要要点之一就是可移植性(除了连接程序,而不是替换它们)。
在sh
,有一种简单的方法可以检查 “is-prefix” 条件。
case $HOST in node*)
# Your code here
esac
鉴于 sh 的年代久远,晦涩难懂(而且 Bash 不能治愈:它更复杂,一致性更差,更不便于移植),我想指出一个非常不错的功能方面:尽管有些语法元素(例如case
是在结果上,构造与其他工作没有什么不同。它们可以用相同的方式组成:
if case $HOST in node*) true;; *) false;; esac; then
# Your code here
fi
甚至更短
if case $HOST in node*) ;; *) false;; esac; then
# Your code here
fi
甚至更短(仅以!
但这是不好的风格)
if ! case $HOST in node*) false;; esac; then
# Your code here
fi
如果您喜欢露骨的话,请构建自己的语言元素:
beginswith() { case $2 in "$1"*) true;; *) false;; esac; }
这实际上不是很好吗?
if beginswith node "$HOST"; then
# Your code here
fi
而且由于sh
基本上只是作业和字符串列表(以及内部进程,由作业组成),我们现在甚至可以执行一些轻量级的函数编程:
beginswith() { case $2 in "$1"*) true;; *) false;; esac; }
checkresult() { if [ $? = 0 ]; then echo TRUE; else echo FALSE; fi; }
all() {
test=$1; shift
for i in "$@"; do
$test "$i" || return
done
}
all "beginswith x" x xy xyz ; checkresult # Prints TRUE
all "beginswith x" x xy abc ; checkresult # Prints FALSE
真优雅并不是说我建议在sh
因为它在现实世界的要求上会很快崩溃(没有 lambda,所以我们必须使用字符串。但是不能使用字符串嵌套函数调用,不能使用管道,等等)。