Shell脚本

#! 告诉系统其后路径所指定的程序即是解释此脚本文件的 Shell 程序。

在Linux中,直接用/bin/sh test.sh指令运行shell脚本文件,这里是调用Bourne Shell解释器。

1. Shell变量

定义变量时,变量名不加美元符号($)变量名和等号之间不能有空格。同时,变量名的命名须遵循如下规则:
命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。
中间不能有空格,可以使用下划线(_)。
不能使用标点符号。
不能使用bash里的关键字(可用help命令查看保留关键字)。
除了显式地直接赋值,还可以用语句给变量赋值

使用一个定义过的变量,只要在变量名前面加美元符号($)即可。

your_name="qinjx"
echo $your_name
echo ${your_name}

变量名外面的花括号是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界,推荐在使用变量时都加上花括号。

使用 readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变。

使用 unset 命令可以删除变量。

2. Shell字符串

字符串可以用单引号,也可以用双引号,也可以不用引号。

单引号字符串的限制:
单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;
单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用。

双引号的优点:
双引号里可以有变量;
双引号里可以出现转义字符。

    your_name='runoob'
    str="Hello, I know you are \"$your_name\"! \n"
    echo -e $str
	输出结果为:`Hello, I know you are "runoob"!`
	
    获取字符串长度
    string="abcd"
    echo ${#string} #输出 4
	
	获得子字符串
	string="runoob is a great site"
    echo ${string:1:4} # 输出 unoo   //str:startIndex:endIndex
	
	查找字符的下标
	string="runoob is a great site"
    echo `expr index "$string" io`  # 输出 4,查找字符 i 或 o 的位置(哪个字母先出现就计算哪个)
    注意: 以上脚本中 ` 是反引号,而不是单引号 '。

3. Shell 数组

bash支持一维数组(不支持多维数组),并且没有限定数组的大小。

定义数组的一般形式为(数组元素用"空格"符号分割开):
数组名=(值1 值2 … 值n)

读取数组:	${数组名[下标]}
使用 @或* 符号可以获取数组中的所有元素,例如:

echo ${array_name[@/*]}

	获取数组的长度:
    # 取得数组元素的个数
	length=${#array_name[@]}
    #或者
	length=${#array_name[*]}
    #取得数组单个元素的长度
    lengthn=${#array_name[n]}

4 .注释

单行注释 用#

多行注释
:< 注释内容…
注释内容…
注释内容…
EOF

5. Shell 传递参数

从命令行向shell脚本内传递参数
脚本内获取参数的格式为:$n。n 代表一个数字,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数,以此类推……

处理参数的几个特殊符号:

$# 传递到脚本的参数个数
$* 以一个单字符串显示所有向脚本传递的参数。 如"$*“用「”」括起来的情况、以"$1 $2 …
$n"的形式输出所有参数。 $$ 脚本运行的当前进程ID号 $! 后台运行的最后一个进程的ID号
$@ 与$*相同,但是使用时加引号,并在引号中返回每个参数。 如"$@“用「”」括起来的情况、以"$1" “ 2 " … " 2" … " 2""n” 的形式输出所有参数。
$- 显示Shell使用的当前选项,与set命令功能相同。
$? 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。

6. Shell运算符

Bash不支持数学运行,可以通过awk和expr等其他命令来实现。
Expr是一款表达式计算工具。使用时需要注意:
表达式和运算符之间要有空格,
表达式要被反引号包含

关系运算符
加减乘除求余:expr $a + $bexpr $a - $bexpr $a \* $bexpr $b / $a,expr $b % a ‘ , 赋 值 : a = a`, 赋值:a= aa=b
判断是否相等:[ $a == $b ],条件表达式要放在方括号之间,并且要有空格

关系运算符
关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
[ $a -eq $b ] 检测两个数是否相等
[ $a -ne $b ] 检测两个数是否不相等
[ $a -gt $b ] 检测左边的数是否大于右边的
[ $a -lt $b ] 检测左边的数是否小于右边的
[ $a -ge $b ] 检测左边的数是否大于等于右边的
[ $a -le $b ] 检测左边的数是否小于等于右边的

布尔运算符
[ ! false ] 非运算
[ $a -lt 20 -o $b -gt 100 ] 或运算
[ $a -lt 20 -a $b -gt 100 ] 与运算

逻辑运算符
[[ $a -lt 100 && $b -gt 100 ]] 逻辑的 AND
[[ $a -lt 100 || $b -gt 100 ]] 逻辑的 OR

字符串运算符
[ $a = $b ] 检测两个字符串是否相等,
[ $a != $b ] 检测两个字符串是否不相等
[ -z a ] 检 测 字 符 串 长 度 是 否 为 0 [ − n " a ] 检测字符串长度是否为0 [ -n " a]0[n"a" ] 检测字符串长度是否不为0
[ $a ] 检测字符串是否为空,不为空返回 true。

文件测试运算符
文件测试运算符用于检测 Unix 文件的各种属性
[ -b $file ] 检测文件是否是块设备文件
[ -c $file ] 检测文件是否是字符设备文件
[ -d $file ] 检测文件是否是目录
[ -f $file ] 检测文件是否是普通文件(既不是目录,也不是设备文件)
[ -g $file ] 检测文件是否设置了 SGID 位
[ -k $file ] 检测文件是否设置了粘着位(Sticky Bit)
[ -p $file ] 检测文件是否是有名管道
[ -u $file ] 检测文件是否设置了 SUID 位
[ -r $file ] 检测文件是否可读
[ -w $file ] 检测文件是否可写
[ -x $file ] 检测文件是否可执行
[ -s $file ] 检测文件是否为空(文件大小是否大于0)
[ -e $file ] 检测文件(包括目录)是否存在

7. Shell的echo指令

Shell 的 echo 指令与 PHP 的 echo 指令类似,都是用于字符串的输出

echo可以用于:

显示普通字符串	echo "It is a test"
显示转义字符		echo "\"It is a test\""
显示变量			echo "$name It is a test"
显示换行			echo -e "OK! \n" # -e 开启转义
显示不换行		echo -e "OK! \c" # -e 开启转义 \c 不换行
显示结果定向至文件		echo "It is a test" > myfile
原样输出字符串,不进行转义或取变量(用单引号)	echo '$name\"'
显示命令执行结果		echo `date`

8. Shell的printf命令

printf 使用引用文本或空格分隔的参数,外面可以在 printf 中使用格式化字符串,还可以制定字符串的宽度、左右对齐方式等。默认 printf 不会像 echo 自动添加换行符,我们可以手动添加 \n。

printf  format-string(单双引号一样)  [arguments...]

格式只指定了一个参数,但多出的参数仍然会按照该格式输出,format-string 被重用

\a	警告字符,通常为ASCII的BEL字符
\b	后退
\c	抑制(不显示)输出结果中任何结尾的换行字符(只在%b格式指示符控制下的参数字符串中有效),而且,任何留在参数里的字符、任何接下来的参数以及任何留在格式字符串中的字符,都被忽略
\f	换页(formfeed)
\n	换行
\r	回车(Carriage return)
\t	水平制表符
\v	垂直制表符
\\	一个字面上的反斜杠字符
\ddd	表示1到3位数八进制值的字符。仅在格式字符串中有效
\0ddd   表示1到3位的八进制值字符

9. Shell的test命令

Shell中的 test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试。

数值测试

-eq	等于则为真
-ne	不等于则为真
-gt	大于则为真
-ge	大于等于则为真
-lt	小于则为真
-le	小于等于则为真
num1=100
num2=100
if test $[num1] -eq $[num2]
then
    echo '两个数相等!'
else
    echo '两个数不相等!'
fi

字符串测试

=	等于则为真
!=	不相等则为真
-z 字符串	字符串的长度为零则为真
-n 字符串	字符串的长度不为零则为真

文件测试

-e 文件名	如果文件存在则为真
-r 文件名	如果文件存在且可读则为真
-w 文件名	如果文件存在且可写则为真
-x 文件名	如果文件存在且可执行则为真
-s 文件名	如果文件存在且至少有一个字符则为真
-d 文件名	如果文件存在且为目录则为真
-f 文件名	如果文件存在且为普通文件则为真
-c 文件名	如果文件存在且为字符型特殊文件则为真
-b 文件名	如果文件存在且为块特殊文件则为真

另外,Shell还提供了与( -a )、或( -o )、非( ! )三个逻辑操作符用于将测试条件连接起来,其优先级为:"!“最高,”-a"次之,"-o"最低。

10. Shell 流程控制

if 语句语法格式:

if condition
then
command1 
command2
  ...
commandN 
	else
		command
fi

for循环一般格式为:

for var in item1 item2 ... itemN
do
    command1
    command2
    ...
    commandN
done

while 语句

while condition
do
    command
done

Shell case语句为多选择语句。可以用case语句匹配一个值与一个模式,如果匹配成功,执行相匹配的命令。case的语法和C family语言差别很大,它需要一个esac(就是case反过来)作为结束标记,每个case分支用右圆括号,用两个分号表示break。

case 值 in
模式1)
    command1
    command2
    ...
    commandN
    ;;
模式2)
    command1
    command2
    ...
    commandN
    ;;
esac

Shell中可以使用break和continue来跳出循环或跳到下一次循环

11. Shell 函数

linux shell 可以用户定义函数,然后在shell脚本中可以随便调用。
shell中函数的定义格式如下:

[ function ] funname [()]
{
    action;
    [return int;]
}

1、可以带function fun() 定义,也可以直接fun() 定义,不带任何参数。
2、参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0-255
3、函数返回值在调用该函数后通过 $? 来获得。.
4、所有函数在使用前必须定义。这意味着必须将函数放在脚本开始部分,直至shell解释器首次发现它时,才可以使用。调用函数仅使用其函数名即可。

参数
在Shell中,调用函数时可以向其传递参数。在函数体内部,通过 $n 的形式来获取参数的值,例如,$1表示第一个参数, 2 表 示 第 二 个 参 数 . . 当 n > = 10 时 , 需 要 使 用 2表示第二个参数.. 当n>=10时,需要使用 2..n>=10使{n}来获取参数。
处理参数的几个特殊符号:
$# 传递到脚本的参数个数
$* 以一个单字符串显示所有向脚本传递的参数。
如"$*“用「”」括起来的情况、以"$1 $2 … $n"的形式输出所有参数。
$$ 脚本运行的当前进程ID号
$! 后台运行的最后一个进程的ID号
$@ 与$*相同,但是使用时加引号,并在引号中返回每个参数。
如"$@“用「”」括起来的情况、以"$1" “ 2 " … " 2" … " 2""n” 的形式输出所有参数。
$- 显示Shell使用的当前选项,与set命令功能相同。
$? 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。

12. Shell 输入/输出重定向

Unix系统一般是从终端接收输入病将输出发送到终端。在Shell中,也可以使用重定向将输入输出重定向指向文件。
重定向命令列表如下:

command > file		将输出重定向到 file。即执行command然后将输出存入file。覆盖写入。
command < file		将输入重定向到 file。即将file的内容作为command的输入。
command >> file		将输出以追加的方式重定向到 file。
n > file			将文件描述符为 n 的文件重定向到 file。
n >> file			将文件描述符为 n 的文件以追加的方式重定向到 file。
n >& m				将输出文件 m 和 n 合并。
n <& m				将输入文件 m 和 n 合并。
<< tag				将开始标记 tag 和结束标记 tag 之间的内容作为输入。

需要注意的是文件描述符 0 通常是标准输入(STDIN),1 是标准输出(STDOUT),2 是标准错误输出(STDERR)。

cat file 可以查看文件内容

一般情况下,每个 Unix/Linux 命令运行时都会打开三个文件:
标准输入文件(stdin):stdin的文件描述符为0,Unix程序默认从stdin读取数据。
标准输出文件(stdout):stdout 的文件描述符为1,Unix程序默认向stdout输出数据。
标准错误文件(stderr):stderr的文件描述符为2,Unix程序会向stderr流中写入错误信息。
默认情况下,command > file 将 stdout 重定向到 file,command < file 将stdin 重定向到 file。
如果希望 stderr 重定向到 file,可以这样写 command 2 > file.
如果希望将 stdout 和 stderr 合并后重定向到 file,可以这样写command > file 2>&1或者command >> file 2>&1。
如果希望对 stdin 和 stdout 都重定向,可以这样写command < file1 >file2。

Here Document 是 Shell 中的一种特殊的重定向方式,用来将输入重定向到一个交互式 Shell 脚本或程序。
它的基本的形式如下:

command << delimiter
    document
delimiter

它的作用是将两个 delimiter 之间的内容(document) 作为输入传递给 command。结尾的delimiter 一定要顶格写,前面不能有任何字符,后面也不能有任何字符,包括空格和 tab 缩进。开始的delimiter前后的空格会被忽略掉。

如果希望执行某个命令,但又不希望在屏幕上显示输出结果,那么可以将输出重定向到 /dev/null

command > /dev/null

/dev/null 是一个特殊的文件,写入到它的内容都会被丢弃;如果尝试从该文件读取内容,那么什么也读不到。但是 /dev/null 文件非常有用,将命令的输出重定向到它,会起到"禁止输出"的效果。

如果希望屏蔽 stdout 和 stderr,可以这样写:
command > /dev/null 2>&1

你可能感兴趣的:(Shell脚本)