if [ $HOST == node* ]
then
echo yes
fi
我该如何正确地做呢?
我还需要结合表达式来检查
HOST
是否为"user1"或以"node"开头。if [ [[ $HOST == user1 ]] -o [[ $HOST == node* ]] ];
then
echo yes
fi
> > > -bash: [: too many arguments
怎样才能正确地做到呢?
if [ $HOST == node* ]
then
echo yes
fi
我该如何正确地做呢?
HOST
是否为"user1"或以"node"开头。if [ [[ $HOST == user1 ]] -o [[ $HOST == node* ]] ];
then
echo yes
fi
> > > -bash: [: too many arguments
这段代码片段来自Advanced Bash Scripting Guide,它表示:
# 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
语法很难适应(在我看来)。
[[ $a == z* ]]
和 [[ $a == "z*" ]]
之间是否有功能上的差异?换句话说,它们的工作方式是否不同?当你说 "$a 等于 z*" 时,具体是什么意思? - Niels Bom[[ $a == *com ]]
。请注意,此处的 *
表示任意数量的字符。 - lepe如果您正在使用较新版本的Bash(v3+),我建议使用Bash正则表达式比较运算符=~
,例如:
if [[ "$HOST" =~ ^user.* ]]; then
echo "yes"
fi
为了在正则表达式中匹配this or that
,使用|
,例如:
if [[ "$HOST" =~ ^user.*|^host1 ]]; then
echo "yes"
fi
user*
表示 use
和零个或多个 r
,因此将匹配 use
和 userrrr
。
- user.*
表示 user
和零个或多个任意字符,因此将匹配 user1
、userX
。
- ^user.*
表示在 $HOST 的开头匹配模式 user.*
。=~
操作符只有在右侧未加引号时才执行正则表达式匹配。如果您对右侧进行引号包含,则“模式的任何部分都可以引用以强制其作为字符串匹配”。即使进行参数扩展,也不应引用右侧。我总是尽量使用POSIX sh
而不是使用Bash扩展功能,因为脚本编写的一个主要目标是可移植性(除了连接程序,而不是替换它们)。
在sh
中,有一种简单的方法可以检查“前缀匹配”条件。
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,所以我们必须使用字符串。但是嵌套函数调用和管道是不可能的等等)。
case $HOST in user01 | node* ) ...
- tripleeeif case $HOST in node*) true;; *) false;; esac; then
我在这里和那里看到过它,但在我看来它看起来有点紧凑。 - Niels Bomcase
命令是命令,它们可以放在if...then
语句中。 - Jo Socase
语法一开始可能看起来古怪和令人困惑,但你很快就会习惯它。为了能够阅读其他人编写的脚本,即使你不打算自己使用它,你也应该掌握这个结构的基本知识。 (就我个人而言,在所有稍有不同的变体中,我倾向于使用它而不是 if [[ $string something...
。POSIX 兼容性是一个不错的奖励。) - tripleee您可以仅选择要检查的字符串部分:
if [ "${HOST:0:4}" = user ]
对于您的后续问题,您可以使用一个OR:
if [[ "$HOST" == user1 || "$HOST" == node* ]]
${HOST:0:4}
用双引号括起来。 - Jo SoHOST='a b'; if [ ${HOST:0:4} = user ] ; then echo YES ; fi
- Jo Soif [[ ${HOST:0:4} = user ]]
- Zim我更喜欢已经发布的其他方法,但有些人喜欢使用:
case "$HOST" in
user1|node*)
echo "yes";;
*)
echo "no";;
esac
编辑:
我已将您提供的备选项添加到上面的case语句中。
在您编辑后的版本中,括号过多。应该是这样的:
if [[ $HOST == user1 || $HOST == node* ]];
[[ $host == user* ]]
可能比 [ "${host#user}" != "${host}" ]
更必要,因为前者更容易阅读。如果您控制脚本执行的环境(针对最新版本的bash
),则应优先选择前者。 - x-yurihas_prefix()
函数中,并且永远不再查看它。 - dhke由于在 Bash 中 # 有特殊意义,我得到了以下解决方案。
另外,我更喜欢使用 "" 包装字符串来避免空格等问题。
A="#sdfs"
if [[ "$A" == "#"* ]];then
echo "Skip comment line"
fi
case $A in "#"*) echo "Skip comment line";; esac
既短又便携。 - tripleee将Mark Rushakoff的最高排名答案的语法细节添加一点更多的细节。
该表达式
$HOST == node*
也可以写作
$HOST == "node"*
效果是一样的。只需确保通配符在引号外部,如果通配符在引号内部,它将被视为字面意思(即不作为通配符)。效果是一样的。只需确保通配符在引号外部,如果通配符在引号内部,它将被视为字面意思(即不作为通配符)。
保持简单
word="appel"
if [[ $word = a* ]]
then
echo "Starts with a"
else
echo "No match"
fi
@OP,对于你的两个问题,你可以使用case/esac:
string="node001"
case "$string" in
node*) echo "found";;
* ) echo "no node";;
esac
case "$HOST" in
node*) echo "ok";;
user) echo "ok";;
esac
case "$HOST" in
node*|user) echo "ok";;
esac
Or Bash 4.0
case "$HOST" in
user) ;&
node*) echo "ok";;
esac
;&
仅适用于 Bash >= 4。 - Dennis Williamson