快速了解和学习Unix/Linux下Shell(四)

Tags: linux shell bash

这篇文章是快速了解和学习Unix/Linux下Shell的第四部分,前几部分参考:

  1. 快速了解和学习Unix/Linux下Shell(一)

  2. 快速了解和学习Unix/Linux下Shell(二)

  3. 快速了解和学习Unix/Linux下Shell(三)

一、printf命令

printf 命令可以理解为增强的echo命令,用于格式化输出。它是C语言printf()库函数的一个有限的变形,并且在语法上有些不同。

注意:printf 由 POSIX 标准所定义,移植性要比echo好。如同echo命令,printf 命令也可以输出简单的字符串,printf命令语法为:

printf  format-string  [arguments...]

说明:

  • printf 命令不用加括号

  • format-string 为格式控制字符串,可以没有引号,但最好加上,单引号双引号均可。

  • 参数多于格式控制符(%)时,format-string 可以重用,可以将所有参数都转换。

  • arguments 为参数列表,使用空格分隔,不用逗号。

示例一,输出字符串:

$printf "Hello, Shell\n"
Hello, Shell
$

示例二,printf的使用方法

# format-string为双引号
$ printf "%d %s\n" 1 "abc"
1 abc

# 单引号与双引号效果一样
$ printf '%d %s\n' 1 "abc"
1 abc
# 没有引号也可以输出
$ printf %s abcdef
abcdef

# 格式只指定了一个参数,但多出的参数仍然会按照该格式输出,format-string 被重用
$ printf %s abc def
abcdef
$ printf "%s\n" abc def
abc
def
$ printf "%s %s %s\n" a b c d e f g h i j
a b c
d e f
g h i
j

# 如果没有 arguments,那么 %s 用NULL代替,%d 用 0 代替
$ printf "%s and %d \n"
and 0

# 如果以 %d 的格式来显示字符串,那么会有警告,提示无效的数字,此时默认置为 0
$ printf "The first program always prints'%s,%d\n'" Hello Shell
-bash: printf: Shell: invalid number
The first program always prints 'Hello,0'
$

注意,根据POSIX标准,浮点格式%e、%E、%f、%g与%G是“不需要被支持”。这是因为awk支持浮点预算,且有它自己的printf语句。这样 Shell程序中需要将浮点数值进行格式化的打印时,可使用小型的awk程序实现。然而,内建于bash、ksh93和zsh中的printf命令都支持 浮点格式。

二、条件语句

条件语句通过关系运算符判断表达式的真假来决定执行执行的分支。Shell有三种条件语句:

  • if ... fi

  • if ... else ... fi

  • if ... elif ... else ... fi

  • case ... esac

1. if else

if ... else 语句的语法是:

if [ expression ]
then
   Statement(s) to be executed if expression is true
fi

注:

  • 只有expression返回true,才会执行then后边的语句将会被执行。

  • 最后必须以 fi 来结尾闭合 if,fi 就是 if 倒过来拼写。

  • expression和方括号([ ])之间必须有空格,否则会有语法错误。

示例:

#!/bin/sh

a=10
b=20

if [ $a == $b ]
then
echo "a is equal to b"
fi

if [ $a != $b ]
then
echo "a is not equal to b"
fi

结果:

a is not equal to b

2. if ... else ... fi 语句

if ... else ... fi 语句的语法为:

if [ expression ]
then
   Statement(s) to be executed if expression is true
else
   Statement(s) to be executed if expression is not true
fi

说明:如果expression返回true,那么then块的语句将会被执行;否则,执行else块语句。

示例:

#!/bin/sh

a=10
b=20

if [ $a == $b ]
then
echo "a is equal to b"
else
echo "a is not equal to b"
fi

结果:

a is not equal to b

3. if ... elif ... fi 语句

if ... elif ... fi 语句可以对多个条件进行判断,语法为:

if [ expression 1 ]
then
   Statement(s) to be executed if expression 1 is true
elif [ expression 2 ]
then
   Statement(s) to be executed if expression 2 is true
elif [ expression 3 ]
then
   Statement(s) to be executed if expression 3 is true
else
   Statement(s) to be executed if no expression is true
fi

说明:任何一个expression的值为true时,会执行对应的then语句块;如果都为false,那么不执行任何语句。

示例:

#!/bin/sh

a=10
b=20

if condition1
then

    command1
elif condition2
then

    command2
else

    commandN
fi

结果:

a is less than b

此外,if else语句可以写在一行里面,如:

if test $[2*3] -eq $[1+5]; then echo 'The two numbers are equal!'; fi;

4. 与test命令合作使用

if ... else 语句经常与 test 命令结合使用(test命令用于检查某个条件是否成立,与方括号[ ]类似),如下所示:

num1=$[2*3]
num2=$[1+5]
if test $[num1] -eq $[num2]
then
echo 'The two numbers are equal!'
else
echo 'The two numbers are not equal!'
fi

结果:

The two numbers are equal!

5. 多分支选择语句

case ... esac与其他语言中的 switch ... case 语句类似,是一种多分枝选择语句。case语句用于匹配一个值或一个模式,如果匹配成功就执行相匹配的命令。case语句格式如下:

case 值 in
模式1)
    command1
    command2
    command3
    ;;
模式2)
    command1
    command2
    command3
    ;;
*)
    command1
    command2
    command3
    ;;
esac

说明:

  • 值可以为变量或常数

  • 值后面必须有关键字 in

  • 所有模式必须以右括号结束

  • 取值将检测匹配的每一个模式

  • 匹配发现取值匹配某一模式后,模式中定义所有命令将会被执行至';;',';;'与其他语言中的break类似,意思是跳到整个 case 语句的最后。

  • 一旦模式匹配,则执行完匹配模式相应命令后不再继续匹配其他模式

  • 如果无一匹配模式,使用星号 * 捕获该值,再执行后面的命令

示例1:

echo 'Input a number between 1 to 4'
echo 'Your number is:\c'
read aNum
case $aNum in
1) echo 'You select 1'
;;
2) echo 'You select 2'
;;
3) echo 'You select 3'
;;
4) echo 'You select 4'
;;
*) echo 'You do not select a number between 1 to 4'
;;
esac

根据用户输入信息不通显示信息,如果输入不是数字,那么显示错误提示。结果:

Input a number between 1 to 4
Your number is:3
You select 3

示例2:

#!/bin/bash

option="${1}"
case ${option} in
-f) FILE="${2}"
echo "File name is $FILE"
;;
-d) DIR="${2}"
echo "Dir name is $DIR"
;;
*)
echo "`basename ${0}`:usage: [-f file] | [-d directory]"
exit 1 # Command to come out of the program with status 1
;;
esac

结果:

$./test.sh
test.sh: usage: [ -f filename ] | [ -d directory ]
$ ./test.sh -f index.htm
$ vi test.sh
$ ./test.sh -f index.htm
File name is index.htm
$ ./test.sh -d unix
Dir name is unix
$

本文链接:http://www.4byte.cn/learning/119984/kuai-su-liao-jie-he-xue-xi-unix-linux-xia-shell-si.html