初识Bash编程

在前一篇文章里面(怎样入Bash编程的坑?),我们列出了的很多Bash的资料。这篇文章是其中一篇的整理而来,原文的地址为Bash — Standard Shell

Bash Conditionals — 条件语句

基本的选择

最基础的条件语句就是if了:

if something ; then
    do_stuff;
fi

fi收尾,这个千万不要忘了。

多条分支的条件语句

这个很显然了,使用elseelif来走不同的逻辑分支:

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,其中操作符可以为

OperatorPurpose
==或者=字符串相等
!=字符串不等
<按字典顺序小于
>按字典顺序大于
=~正则匹配(Bash 3 Only)

字符串检验

通常字符串检验的形式为-operator "string",其中操作符可以为

OperatorPurpose
-z字符串长度为0
-n字符串长度非0

注意:如果你确认一个变量被设置了而且非空,使用`-n “${BLAH}”,而非”-n $BLAH”,后一种情况在变量未设置时会出错。

整型数比较

通常整型数比较的形式为int1 -operator int2,可选的操作符如下:

OperatorPurpose
-eq等于
-ne不等
-lt小于
-le小于或等于
-gt大于
-ge大于或等于

文件检验

文件检验的形式为-operator "filename",其中操作符为可以:

OperatorPurpose
-a fileExists (use -e instead)
-b fileExists and is a block special file
-c fileExists and is a character special file
-d fileExists and is a directory
-e fileExists
-f fileExists and is a regular file
-g fileExists and is set-group-id
-h fileExists and is a symbolic link
-k fileExists and its sticky bit is set
-p fileExists and is a named pipe (FIFO)
-r fileExists and is readable
-s fileExists and has a size greater than zero
-t fdDescriptor fd is open and refers to a terminal
-u fileExists and its set-user-id bit is set
-w fileExists and is writable
-x fileExists and is executable
-O fileExists and is owned by the effective user id
-G fileExists and is owned by the effective group id
-L fileExists and is a symbolic link
-S fileExists and is a socket
-N fileExists and has been modified since it was last read

文件比较

文件比较的一般形式为"fille1" -operator "file2"。其中 操作符如下:

OperatorPurpose
file1 -nt file2文件1比文件2更新(根据修改日期比较),或者文件1存在而文件2不存在
file1 -ot file2文件1比文件2更旧,或者文件1不存在而文件2存在
file1 -ef file2file1 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语言是一样的:

OperatorsEffect
var++, var–Variable post-increment, post-decrement
++var, –varVariable 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 : exprConditional operator
=, *=, /=, %=, +=, -=, <<=, >>=, &=, ^=, | =Assignment
expr1 , expr2Multiple statements

|

    原文作者:治部少辅
    原文地址: https://www.jianshu.com/p/d590aa13b124
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞