我总是尝试坚持使用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,所以我们必须使用字符串。但是用字符串嵌套函数调用是不可能的,管道是不可能的,等等。)