在前一篇文章里面(怎样入Bash编程的坑?),我们列出了的很多Bash的资料。这篇文章是其中一篇的整理而来,原文的地址为Bash -- Standard Shell
Bash Conditionals -- 条件语句
基本的选择
最基础的条件语句就是if
了:
if something ; then
do_stuff;
fi
以fi
收尾,这个千万不要忘了。
多条分支的条件语句
这个很显然了,使用else
和elif
来走不同的逻辑分支:
if something ; then
do_stuff
elif something_else ; then
do_other_stuff
elif full_moon ; then
howl
else
turn_into_a_newt
fi
注意,在条件语句下,每个区块中必须要有至少一行语句,即下面的写法是错误的:
if some_stuff ; then
# A statement is required here. a blank or a comment
# isn't enough!
else
einfo "Not some stuff"
fi
如果你实在是没有语句可以放,可以用:
来表示空语句,类似python中的pass
:
if some_stuff ; then
# Do nothing
:
else
einfo "Not some stuff"
fi
条件检验
进行比对或者是文件的属性检验时,相关的语句需要用[]
或者[[]]
框起来
# is $foo zero length?
if [[ -z "${foo}" ]] ; then
die "Please set foo"
fi
# is $foo equal to "moo"?
if [[ "${foo}" == "moo" ]] ; then
einfo "Hello Larry"
fi
# does "${ROOT}/etc/deleteme" exist?
if [[ -f "${ROOT}/etc/deleteme" ]] ; then
einfo "Please delete ${ROOT}/etc/readme manually!"
fi
注意一般
[[]]
要比[]
安全一些,尽量多使用前者吧
这是因为[[]]
是bash的一个语法结构,而[]
中框起来的语句其实是被视为内联的。看下面这个例子:
bash$ [ -n $foo ] && [ -z $foo ] && echo "huh?"
huh?
bash$ [[ -n $foo ]] && [[ -z $foo ]] && echo "huh?"
bash$
字符串比对
一般的字符串比对形式为string1 operator string2
,其中操作符可以为
Operator | Purpose |
---|---|
== 或者=
|
字符串相等 |
!= |
字符串不等 |
< |
按字典顺序小于 |
> |
按字典顺序大于 |
=~ |
正则匹配(Bash 3 Only) |
字符串检验
通常字符串检验的形式为-operator "string"
,其中操作符可以为
Operator | Purpose |
---|---|
-z |
字符串长度为0 |
-n |
字符串长度非0 |
注意:如果你确认一个变量被设置了而且非空,使用`-n "${BLAH}",而非"-n $BLAH",后一种情况在变量未设置时会出错。
整型数比较
通常整型数比较的形式为int1 -operator int2
,可选的操作符如下:
Operator | Purpose |
---|---|
-eq |
等于 |
-ne |
不等 |
-lt |
小于 |
-le |
小于或等于 |
-gt |
大于 |
-ge |
大于或等于 |
文件检验
文件检验的形式为-operator "filename"
,其中操作符为可以:
Operator | Purpose |
---|---|
-a file |
Exists (use -e instead) |
-b file |
Exists and is a block special file |
-c file |
Exists and is a character special file |
-d file |
Exists and is a directory |
-e file |
Exists |
-f file |
Exists and is a regular file |
-g file |
Exists and is set-group-id |
-h file |
Exists and is a symbolic link |
-k file |
Exists and its sticky bit is set |
-p file |
Exists and is a named pipe (FIFO) |
-r file |
Exists and is readable |
-s file |
Exists and has a size greater than zero |
-t fd |
Descriptor fd is open and refers to a terminal |
-u file |
Exists and its set-user-id bit is set |
-w file |
Exists and is writable |
-x file |
Exists and is executable |
-O file |
Exists and is owned by the effective user id |
-G file |
Exists and is owned by the effective group id |
-L file |
Exists and is a symbolic link |
-S file |
Exists and is a socket |
-N file |
Exists and has been modified since it was last read |
文件比较
文件比较的一般形式为"fille1" -operator "file2"
。其中 操作符如下:
Operator | Purpose |
---|---|
file1 -nt file2 |
文件1比文件2更新(根据修改日期比较),或者文件1存在而文件2不存在 |
file1 -ot file2 |
文件1比文件2更旧,或者文件1不存在而文件2存在 |
file1 -ef file2 |
file1 and file2 refer to the same device and inode numbers. |
布尔运算
||
或,&&
与,!
非。
注意:在
[[]]
内部,[[ ! -f file ]] && bar
可以工作,而[[ -f foo && bar]]
则无法正常工作,这是因为[[]]
内无法运行命令。
Bash中的遍历结构
和其他的编程语言类似,遍历结构分为两种,for
关键词和while
关键词。
下面是一些例子的
for myvar in "the first" "the second" "and the third" ; do
einfo "This is ${myvar}"
done
for (( i = 1 ; i <= 10 ; i++ )) ; do
einfo "i is ${i}"
done
while hungry ; do
eat_cookies
done
Bash中的变量操作
在bash中,关于${}
结构,在一些情况下可以用来操作变量或者获取变量的信息。使用这个特性可以避免相对来说比较耗性能的(或者illegal的)sed
系列指令。
获取字符串长度
${#somevar}
可以用来获取字符串的长度
somevar="Hello World"
echo "${somevar} is ${#somevar} characters long"
变量的默认值
Bash中有很多的方法来为未设置或者空的变量设置一个默认值。${var:-value}
这个结构,在var
未设置或者为空的时候为var
提供默认值value
。${var-value}
的功能基本是相同的,但是如果var
这个变量被声明了,但是为空,此时两者的表现会不同:
var= # declared but not set
echo ${var:-default} # var获得默认值default
var2= # declared but not set
echo ${var2-default} # var仍为空
${var:=value}
和${var=value}
在var
没有设置值时(null
)为其填充value
值。冒号的作用和上面的是一样的。
${var:?message}
这个命令,会在var
这个变量未设置或者为空时,显示message
的信息并终止程序。这里也有去掉冒号的形式${var?message}
.
${var:+value}
命令作用恰好想法,如果var
有值了,则返回value
,否则返回空字符串。
提取substring
提取substring,主要是使用到${var:offset}
和${var:offset:length}
,这两个命令。其中offset
参数的作用方式和python是类似的,当offset
为正数时,偏移量从左至右算,为负数时从右至左算。
Command Substitution
$(command)
这个命令可以将command
命令的stdout
输出捕获并返回为一个字符串。
注意:
\
command`也可以起到类似的作用,但是你最好还是使用
$(command)`,毕竟后者更加简洁可读,也方便嵌套使用。
字符串替换
Bash中一共提供了三种字符串替换的方式: ${var#pattern}
,${var%pattern}
,${var/pattern/replacement}
。前两个用来进行删除操作。
${var#pattern}
命令会返回将var
的,从字符串其实处开始的符合pattern
的最短的子字符串删除之后余下的结果,如果没有匹配的,则返回var
本身。如果要删除最长的子字符串,使用${var##pattern}
${var%pattern}
类似,不过子字符串从字符串尾部算起。相应的,如果想用贪心模式,重复百分号即可${var%%pattern}
。
${var/pattern/replacement}
可以用replacement
替换第一个匹配项。如果想要替换所有的匹配项 ,就需要使用${var//pattern/replacement}
Bash的代数计算扩展
$(( expression))
这个机构提供了代数计算的扩展,其中expression
表达式有着类C的结构。下面是你可以采用操作符,他们的定义基本是和C语言是一样的:
Operators | Effect |
---|---|
var++, var-- | Variable post-increment, post-decrement |
++var, --var | Variable pre-increment, pre-decrement |
-, + | Unary minus and plus |
!, ~ | Logical negation, bitwise negation |
** | Exponentiation |
*, /, % | Multiplication, division, remainder |
+, - | Addition, subtraction |
<<, >> | Left, right bitwise shifts |
<=, >=, <, > | Comparison: less than or equal to, greater than or equal to, strictly less than, strictly greater than |
==, != | Equality, inequality |
& | Bitwise AND |
^ | Bitwise exclusive OR |
| | Bitwise OR |
&& | Logical AND |
| | | Logical OR |
expr ? expr : expr | Conditional operator |
=, *=, /=, %=, +=, -=, <<=, >>=, &=, ^=, | = | Assignment |
expr1 , expr2 | Multiple statements |
|