前序
- shell是一种应用程序,它可以提供一个供用户访问操作系统内核服务的界面。
- shell是一种解释性编程语言,可以编写脚本程序来实现复杂的功能。
shell作为一种脚本语言,必须要有解释器来解释执行;bash是大多数Linux系统默认的shell解释器。
所以,一般脚本开头都有#! /bin/bash这样的约定标识,它告诉系统这个脚本需要什么解释器来执行。
脚本的执行:
关于注释:使用#进行单行注释
变量
定义变量:
country="China“
Number=100
注意:
- 变量名和等号之间不能有空格
- 首个字符必须为字母(a-z,A-Z)
- 中间不能有空格,可以使用下划线(_)
- 不能使用标点符号
- 不能使用bash里的关键字
使用变量:
在一个定义过的变量前面加上 就可以了, 比如:echo country或者echo ${country}
其中,对于变量的{} 是可以选择的,目的是帮助解释器识别变量的边界。
重定义变量:
country="China“
country=“ribenguizi“
只读变量:
readonly country="China“
删除变量:
unset country
特殊变量:
注意:
∗和@ 的区别为:∗和@ 都表示传递给函数或脚本的所有参数,不被双引号(" ")包含时,都以"1""2" … "n"的形式输出所有参数。
但是当它们被双引号("")包含时,"*" 会将所有的参数作为一个整体,以"12 … n"的形式输出所有参数;
"@" 会将各个参数分开,以"1""2" … "$n" 的形式输出所有参数。
$?:可以获取上一个命令的退出状态。所谓退出状态,就是上一个命令执行后的返回结果。退出状态是一个数字,一般情况下,
大部分命令执行成功会返回 0,失败返回 1。
读取用户输入:
read <variable_name> 或者 read –p “message” < variable_name >
命令替换:把一个命令的输出赋值给一个变量
directory=`pwd` 或者 directory=$(pwd)
字符串
- 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;
- 单引号字串中不能出现单引号(对单引号使用转义符后也不行)。但可成对出现,作为字符串拼接使用。
双引号的优点:
- 双引号里可以有变量
- 双引号里可以出现转义字符
拼接字符串:
country=“China”
echo “hello, $country”
echo “hello, “$country” ”
echo ‘hello, $country’
echo ‘hello, ‘$country’ ’
获取字符串长度:
string="abcd"
echo ${#string} #输出 4
变量为数组时,${#string} 等价于${#string[0]}
提取子字符串:
string=“ctyun is a great company"
echo ${string:1:4} #输出tyun
echo ${string:(-7):5} #输出compa
注意:第一个字符的索引值为 0。
数组
bash只支持一维数组,下标从0开始。
定义数组:在shell中用括号表示数组,元素用空格分开。 如:fruit=(apple pear ban)
读取数组:
读取某个下标的元素,一般格式为:
${array_name[index]}
读取数组的全部元素,用@或*:
${array_name[*]}
或者
${array_name[@]}
获取数组信息:
取得数组元素的个数:
length=${#array_name[@]}
或者
length=${#array_name[*]}
取得数组单个元素的长度:
lengthn=${#array_name[n]}
运算符
算术运算符:原生bash不支持简单的数学运算,但可以通过expr命令实现。
- 在expr中的乖号为:\*,并且表达式与运算符之间要有空格,否则报错;
- 算术运算也可以通过$(( ))或者$[ ],这种形式的话,没有上述限制。
比如:`expr 2 \* 3`或者$((2*3)) 或者$[2*3]
关系运算符:关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
- 条件表达式要放在方括号之间,并且方括号与变量、变量与运算符之间都需要有空格,否则报错!
- 另外也可以采用test命令,来检查条件是否成立。比如:test $a –eq $b等价于[ $a –eq $b ]
布尔运算符:
运算符 | 说明 |
! | 非运算,表达式为 true 则返回 false,否则返回 true。 |
-o | 或运算,有一个表达式为 true 则返回 true。 |
-a | 与运算,两个表达式都为 true 才返回 true。 |
逻辑运算符:
运算符 | 说明 |
&& | 逻辑的 AND |
|| | 逻辑的 OR |
示例:
read –p “are you sure? [y/n]” flag
[ $flag = “y” –o $flag = “Y” ]
[ $flag = “y” ] || [ $flag = “Y” ]
[[ $flag = “y” || $flag = “Y” ]]
字符串运算符:假定变量 a 为 "abc",变量 b 为 "efg"
文件测试运算符:用于检测文件的各种属性。
流程控制
if判断语句:
if condition; then
command
fi
或者
if condition; then
command
else
command
fi
或者
if condition; then
command
elif condition; then
command
else
command
fi
注意:shell的流程控制分支中不能为空,否则报错!
case语句:
case 值 in
模式1)
command1
command2
command3
;;
模式2)
command1
command2
command3
;;
*)
command1
command2
command3
;;
esac
- 取值后面必须为关键字 in,每一模式必须以右括号结束。取值可以为变量或常数。
- 匹配发现取值符合某一模式后,其间所有命令开始执行直至 ;;。
;; 与其他语言中的 break 类似,意思是跳到整个 case 语句的最后。- 如果无一匹配模式,使用星号 * 捕获该值,再执行后面的命令。
循环语句
for循环:
for 变量 in 列表
do
command1
command2
...
commandN
done
类似C语言的三表达式语法:
for ((i=1; i<=10; i++))
do
echo "$i"
done
注意:列表是一组值(数字、字符串等)组成的序列,每个值通过空格分隔。每循环一次,就将列表中的下一个值赋给变量。
while循环:
while condition
do
command
done
until循环:
until condition
do
command
done
注意:until 循环与 while 循环在处理方式上刚好相反。当condition为false时,才执行command;为true时推出循环。
无限循环语法格式:
无限循环语法格式:
while :
do
command
done
或者
while true
do
command
done
或者
until false
do
command
done
或者
for (( ; ; ))
注意:在循环过程中,有时候需要在未达到循环结束条件时强制跳出循环。break、continue,用法与C语言类似。
函数
shell函数必须先定义后使用,定义如下:
function_name ()
{
list of commands
[ return value ]
}
也可以加上function关键字:
function function_name ()
{
list of commands
[ return value ]
}
- 调用函数只需要给出函数名,不需要加括号。
- 函数返回值,可以显式增加return语句;如果不加,会将最后一条命令运行结果作为返回值。
- 函数返回值只能是整数(0-255),一般用来表示函数执行成功与否,0表示成功,其他值表示失败
- 调用函数后可通过$?来获取函数返回值。
- 调用函数时可以向其传递参数;在函数体内部,通过 ${n} 的形式来获取参数的值
输入/输出重定向
命令 | 说明 |
command > file | 将command命令的标准输出重定向到file文件 |
command >> file | 将command命令的标准输出以追加的方式重定向到file文件 |
command < file | 将command命令的标准输入重定向到file文件 |
command > file 2>&1 | 将command命令的标准输出和标准错误输出都重定向到file文件 |
command >> file 2>&1 | 将command命令的标准输出和标准错误输出都以追加的方式重定向到file文件 |
文件包含
shell 也可以包含外部脚本,将外部脚本的内容合并到当前脚本。
. filename 或 source filename
- 两种方式的效果相同,一般使用点号(.),但是注意点号(.)和文件名中间有一空格。
- 被包含脚本不需要有执行权限。