Shell脚本执行
创建shell脚本文件(.sh)并对其进行编辑。
lgs@lgs-virtual-machine:~/Desktop/study/test$ vim test.sh
#!/bin/bash
echo "hello world!"
两种执行方式
①chmod修改权限,使shell脚本文件作为可执行文件。
lgs@lgs-virtual-machine:~/Desktop/study/test$ chmod 777 test.sh
lgs@lgs-virtual-machine:~/Desktop/study/test$ ./test.sh
hello world!
②通过Bash调用执行脚本
lgs@lgs-virtual-machine:~/Desktop/study/test$ bash test.sh
hello world!
多命令顺序执行
符号 | 格式 | 作用 |
---|---|---|
; | order1;order2 | 多个命令顺序执行,命令之间没有任何逻辑联系 |
&& | order1&&order2 | 当order1正确执行order2才会执行,否则order2不会执行 |
|| | order1||order2 | 当order1执行不正确order2才会执行,否则order2不会执行 |
输入输出重定向
linux标准输入输出
设备 | 设备名 | 文件描述符 | 类型 |
---|---|---|---|
键盘 | /dev/stdin | 0 | 标准输入 |
显示器 | /dev/stdout | 1 | 标准输出 |
显示器 | /dev/stderr | 2 | 标准错误输出 |
输入重定向
输入重定向是指不使用系统提供的标准输入端口,而进行重新的指定。换言之,输入重定向就是不使用标准输入端口输入文件,而是使用指定的文件作为标准输入设备。(重定向简单理解就是使用“<"符来修改标准输入设备)。
类型 | 符号 | 功能 |
---|---|---|
标准输入 | 命令<文件 | 命令把文件中的内容作为标准输入设备 |
标识符限定输入 | 命令<<标识符 | 命令把标准输入中读入内容,直到遇到“标识符”分解符为止 |
输入输出重定向 | 命令<文件1>文件2 | 命令把文件1的内容作为标准输入,把文件2作为标准输出 |
lgs@lgs-virtual-machine:~/Desktop/study/test$ cat my.txt
This is my text!
lgs@lgs-virtual-machine:~/Desktop/study/test$ read text < my.txt
lgs@lgs-virtual-machine:~/Desktop/study/test$ echo $text
This is my text!
输出重定向
(通俗的讲,重定向输出就是把要输出的文件信息写入到一个文件中去,而不是将要输出的文件信息输出到控制台(显示屏),在linux中,默认的标准输出设备是控制台(或称为显示器),用户输出的信息默认情况下都会显示到控制台。
类型 | 符号 | 功能 |
---|---|---|
标准输出重定向 | 命令>文件 | 以覆盖方式,把命令的正确输出内容输出到指定的文件或设备当中 |
标准输出重定向 | 命令>>文件 | 以追加方式,把命令的正确输出内容输出到指定的文件或设备当中 |
标准错误输出重定向 | 错误命令>文件 | 以覆盖方式,把命令的错误输出内容输出到指定的文件或设备当中 |
标准错误输出重定向 | 错误命令>>文件 | 以追加方式,把命令的错误输出内容输出到指定的文件或设备当中 |
正确和错误输出同时保存 | 命令>文件 2>&1 | 以覆盖的方式,把命令的正确输出和错误输出都保存到同一个文件当中 |
正确和错误输出同时保存 | 命令>>文件 2>&1 | 以追加的方式,把命令的正确输出和错误输出都保存到同一个文件当中 |
正确和错误输出同时保存 | 命令&>文件 | 以覆盖的方式,把命令的正确输出和错误输出都保存到同一个文件当中 |
正确和错误输出同时保存 | 命令&>>文件 | 以追加的方式,把命令的正确输出和错误输出都保存到同一个文件当中 |
正确和错误输出同时保存 | 命令>>文件1 2>>文件2 | 把正确的输出追加到文件1中,把错误的输出追加到文件2中 |
lgs@lgs-virtual-machine:~/Desktop/study/test$ touch test.txt
lgs@lgs-virtual-machine:~/Desktop/study/test$ str1='I am the first string'
lgs@lgs-virtual-machine:~/Desktop/study/test$ echo $str1 > test.txt
lgs@lgs-virtual-machine:~/Desktop/study/test$ cat test.txt
I am the first string
lgs@lgs-virtual-machine:~/Desktop/study/test$ str2='I am the second string'
lgs@lgs-virtual-machine:~/Desktop/study/test$ echo $str2 > test.txt
lgs@lgs-virtual-machine:~/Desktop/study/test$ cat test.txt
I am the second string
lgs@lgs-virtual-machine:~/Desktop/study/test$ echo $str1 >> test.txt
lgs@lgs-virtual-machine:~/Desktop/study/test$ cat test.txt
I am the second string
I am the first string
Shell变量
命名规则
1.命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。
2.等号左右两侧不能有空格,可以使用下划线“_”,变量的值如果有空格,需要使用单引号或双引号包括。如:“test=“hello world!””。其中
双引号括起来的内容“$”,“(”和反引号都拥有特殊含义,而单引号括起来的内容都是普通字符。
3.不能使用标点符号,不能使用bash里的关键字(可用help命令查看保留关键字)。
4.环境变量建议大写,便于区分。
5.如果需要增加变量的值,那么可以进行变量值的叠加。不过变量需要用双引号包含" 变量名 " 或用 变量名"或用 变量名"或用{变量名}包含变量名。
变量分类
变量 | 说明 |
---|---|
用户自定义变量 | 由用户自由定义变量名和变量的值 |
用户自定义环境变量 | 环境变量的变量名可以由用户定义 |
系统自带环境变量 | 对系统起作用的环境变量的变量名是系统预先设定好的 |
位置参数变量 | 主要是用来向脚本当中传递参数或数据的,变量名不能自定义,变量作用是固定的 |
预定义变量 | 是Bash中已经定义好的变量,变量名不能自定义,变量作用也是固定的 |
特殊符号
符号 | 作用 |
---|---|
’ ’ | 单引号中的所有字符都被当做普通字符原样输出 |
" " | 双引号中特殊符号都没有特殊含义,“$”,“`”(esc键下面)和“\”是例外,拥有“调用变量的值”、“引用命令”和“转义符”的含义 |
`` | 反引号括起来的内容是系统命令,在Bash中会先执行它 |
$( ) | 和反引号作用一样,用来引用系统命令 |
( ) | 用于一串命令执行时,()中的命令会在子Shell中运行 |
{ } | 用于一串命令执行时,{ }中的命令会在当前Shell中执行。也可以用于变量变形与替换 |
[ ] | 用于变量的测试 |
# | 在Shell脚本中,#开头的行代表注释 |
$ | 用于调用变量的值,如需要调用变量name的值时,需要用$name的方式得到变量的值 |
\ | 转义符,跟在\之后的特殊符号将失去特殊含义,变为普通字符。如 将输出“ 将输出“ 将输出“”符号,而不当做是变量引用 |
运算符
算数运算符
运算符 | 表达式 | 说明 |
---|---|---|
加法 | expr $a + $b | 计算a加b |
减法 | expr $a - $b | 计算a减b |
乘法 | expr $a \* $b | 计算a乘以b |
除法 | expr $a / $b | 计算a除以b |
取余 | expr $a % $b | 计算a除以b的余数 |
赋值 | = | 对变量进行赋值 |
相等判断 | == | 判断是否相等,返回true/false |
不相等判断 | != | 判断是否相等,返回true/false |
lgs@lgs-virtual-machine:~/Desktop/study/test$ a=20
lgs@lgs-virtual-machine:~/Desktop/study/test$ b=10
lgs@lgs-virtual-machine:~/Desktop/study/test$ echo "a + b =" `expr $a + $b`
a + b = 30
lgs@lgs-virtual-machine:~/Desktop/study/test$ echo "a - b =" `expr $a - $b`
a - b = 10
lgs@lgs-virtual-machine:~/Desktop/study/test$ echo "a * b =" `expr $a \* $b`
a * b = 200
lgs@lgs-virtual-machine:~/Desktop/study/test$ echo "a / b =" `expr $a / $b`
a / b = 2
lgs@lgs-virtual-machine:~/Desktop/study/test$ echo "a % b =" `expr $a % $b`
a % b = 0
lgs@lgs-virtual-machine:~/Desktop/study/test$ [ $a == $b ]
lgs@lgs-virtual-machine:~/Desktop/study/test$ echo $?
1
lgs@lgs-virtual-machine:~/Desktop/study/test$ [ $a != $b ]
lgs@lgs-virtual-machine:~/Desktop/study/test$ echo $?
0
#在Bash中,0表示true,1表示false
关系运算符
关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
运算符 | 单词 | 说明 |
---|---|---|
-eq | equal | 检测两个数是否相等,相等返回 true |
-ne | not equal | 检测两个数是否相等,不相等返回 true |
-gt | greater than | 检测左边的数是否大于右边的,如果是,则返回 true |
-lt | less than | 检测左边的数是否小于右边的,如果是,则返回 true |
-ge | greater than or equal | 检测左边的数是否大于等于右边的,如果是,则返回 true |
-le | less than or equal | 检测左边的数是否小于等于右边的,如果是,则返回 true |
lgs@lgs-virtual-machine:~/Desktop/study/test$ [ 0 -eq 0 ]
lgs@lgs-virtual-machine:~/Desktop/study/test$ echo $?
0
lgs@lgs-virtual-machine:~/Desktop/study/test$ [ 1 -gt 0 ]
lgs@lgs-virtual-machine:~/Desktop/study/test$ echo $?
0
逻辑运算符
运算符 | 说明 |
---|---|
! | 非运算,表达式为 true 则返回 false,否则返回 true |
-o | 或(或者)运算,有一个表达式为 true 则返回 true |
-a | 与(并且)运算,两个表达式都为 true 才返回 true |
字符串运算符
运算符 | 说明 |
---|---|
= | 检测两个字符串是否相等,相等返回 true |
!= | 检测两个字符串是否相等,不相等返回 true |
-z | 检测字符串长度是否为0,为0返回 true |
-n | 检测字符串长度是否为0,不为0返回 true |
str | 检测字符串是否为空,不为空返回 true |
lgs@lgs-virtual-machine:~/Desktop/study/test$ str1='string1'
lgs@lgs-virtual-machine:~/Desktop/study/test$ str2=$str1
lgs@lgs-virtual-machine:~/Desktop/study/test$ [ $str1 = $str2 ]
lgs@lgs-virtual-machine:~/Desktop/study/test$ echo $?
0
lgs@lgs-virtual-machine:~/Desktop/study/test$ str2='string2'
lgs@lgs-virtual-machine:~/Desktop/study/test$ [ $str1 = $str2 ]
lgs@lgs-virtual-machine:~/Desktop/study/test$ echo $?
1
文件测试运算符
操作符 | 说明 |
---|---|
-b file | 检测文件是否是块设备文件,如果是,则返回 true |
-c file | 检测文件是否是字符设备文件,如果是,则返回 true |
-d file | 检测文件是否是目录,如果是,则返回 true |
-f file | 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true |
-g file | 检测文件是否设置了 SGID 位,如果是,则返回 true |
-k file | 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true |
-p file | 检测文件是否是有名管道,如果是,则返回 true |
-u file | 检测文件是否设置了 SUID 位,如果是,则返回 true |
-r file | 检测文件是否可读,如果是,则返回 true |
-w file | 检测文件是否可写,如果是,则返回 true |
-x file | 检测文件是否可执行,如果是,则返回 true |
-s file | 检测文件是否为空(文件大小是否大于0),不为空返回 true |
-e file | 检测文件(包括目录)是否存在,如果是,则返回 true |
流程控制
if条件判断
单分支if条件判断
if [ 条件判断式 ]
then
条件成立时,执行的程序
fi
双分支if条件判断
if [ 条件判断式 ]
then
条件成立时,执行的程序
else
条件不成立时,执行的另一个程序
fi
多分支if条件判断
if [ 条件判断式1 ]
then
当条件判断式1成立时,执行程序1
elif [ 条件判断式2 ]
then
当条件判断式2成立时,执行程序2
…省略更多条件…
else
当所有条件都不成立时,最后执行此程序
fi
多分支case条件
case和if多分支语句都去有判断多个条件的功能,区别在于if可以判断多种条件关系,而case只能判断一种条件关系。
case $变量名 in
"值1")
如果变量的值等于值1,则执行程序1
;;
"值2")
如果变量的值等于值2,则执行程序2
::
…省略其他分支…
*)
如果变量的值都不是以上的值,则执行此程序
;;
esac
注意:
①case语句,会取出变量中的值,然后与语句体中的值逐一比较。如果数值符合,则执行对应的程序,如果数值不符,则依次比较下一个值。如果所有的值都不符合,则执行 “*)” (*代表所有其他值)中的程序。
②case语句以“case”开头,以“esac”结尾。
③每一个分支程序之后要通过“;;”双分号结尾,代表该程序段结束(千万不要忘记,每次写case语句,都不要忘记双分号)。
lgs@lgs-virtual-machine:~/Desktop/study/test$ vim test1.sh
#!/bin/bash
read -p "请输入一个字符,并按Enter确认:" KEY
case "$KEY" in
[a-z]|[A-Z])
echo "您输入的是字母"
;;
[0-9])
echo "您输入的是数字"
;;
*)
echo "您输入的是其他字符"
;;
esac
lgs@lgs-virtual-machine:~/Desktop/study/test$ bash test1.sh
请输入一个字符,并按Enter确认:2
您输入的是数字
lgs@lgs-virtual-machine:~/Desktop/study/test$ bash test1.sh
请输入一个字符,并按Enter确认:a
您输入的是字母
lgs@lgs-virtual-machine:~/Desktop/study/test$ bash test1.sh
请输入一个字符,并按Enter确认:#
您输入的是其他字符
for循环语句
for循环语法有两种,分别如下。
for 变量 in 值1 值2 值3 …(可以是一个文件等)
do
程序
done
# 示例
lgs@lgs-virtual-machine:~/Desktop/study/test$ vim test2.sh
#!/bin/bash
for time in morning afternoon night
do
echo $time
done
lgs@lgs-virtual-machine:~/Desktop/study/test$ bash test2.sh
morning
afternoon
night
for (( 初始值;循环控制条件;变量变化 ))
do
程序
done
# 示例
lgs@lgs-virtual-machine:~/Desktop/study/test$ vim test3.sh
#!/bin/bash
for (( i=1 ; i <= 9 ; i=i+1 ))
do
for (( j=1 ; j<=i ; j=j+1 ))
do
echo -n $j '*' $i '=' `expr $i \* $j` ' '
done
echo
done
lgs@lgs-virtual-machine:~/Desktop/study/test$ bash test3.sh
1 * 1 = 1
1 * 2 = 2 2 * 2 = 4
1 * 3 = 3 2 * 3 = 6 3 * 3 = 9
1 * 4 = 4 2 * 4 = 8 3 * 4 = 12 4 * 4 = 16
1 * 5 = 5 2 * 5 = 10 3 * 5 = 15 4 * 5 = 20 5 * 5 = 25
1 * 6 = 6 2 * 6 = 12 3 * 6 = 18 4 * 6 = 24 5 * 6 = 30 6 * 6 = 36
1 * 7 = 7 2 * 7 = 14 3 * 7 = 21 4 * 7 = 28 5 * 7 = 35 6 * 7 = 42 7 * 7 = 49
1 * 8 = 8 2 * 8 = 16 3 * 8 = 24 4 * 8 = 32 5 * 8 = 40 6 * 8 = 48 7 * 8 = 56 8 * 8 = 64
1 * 9 = 9 2 * 9 = 18 3 * 9 = 27 4 * 9 = 36 5 * 9 = 45 6 * 9 = 54 7 * 9 = 63 8 * 9 = 72 9 * 9 = 81
while循环语句
对while循环来讲,只要条件判断式成立,循环就会一直继续,直到条件判断式不成立,循环才会停止。
while [ 条件判断式 ]
do
程序
done
# 示例
lgs@lgs-virtual-machine:~/Desktop/study/test$ vim test4.sh
#!/bin/bash
read -p '请输入n的值(用于求解n!,n>=1):' n
i=1
count=1
while [ $i -le $n ]
do
count=$(( $count*$i ))
i=$(( $i+1 ))
done
echo $n'!=' $count
lgs@lgs-virtual-machine:~/Desktop/study/test$ bash test4.sh
请输入n的值(用于求解n!,n>=1):3
3!= 6
until循环语句
和while循环相反,until循环时只要条件判断式不成立则进行循环,并执行循环程序。一旦循环条件成立,则终止循环。
until [ 条件判断式 ]
do
程序
done
# 示例
lgs@lgs-virtual-machine:~/Desktop/study/test$ vim test5.sh
#!/bin/bash
i=1
until [ $i -eq 10 ]
do
echo $i
i=$(( $i+1 ))
done
lgs@lgs-virtual-machine:~/Desktop/study/test$ bash test5.sh
1
2
3
4
5
6
7
8
9
函数
function 函数名 () {
程序
}
# 示例
lgs@lgs-virtual-machine:~/Desktop/study/test$ vim test6.sh
#!/bin/bash
function Cal()
{
i=1
count=0
while [ $i -le $num ]
do
count=$(( $count+$i ))
i=$(( $i+1 ))
done
return $count
}
function Pri()
{
j=1
while [ $j -lt $num ]
do
echo -n $j'+'
j=$(( $j+1 ))
done
Cal $num
result=$?
echo $num'='$result
}
read -p 'please enter a number x(x>1):' num
Pri $num
lgs@lgs-virtual-machine:~/Desktop/study/test$ bash test6.sh
please enter a number x(x>1):6
1+2+3+4+5+6=21
特殊流程控制语句
①exit语句,系统是有exit命令的,用于退出当前用户的登录状态。可是在Shell脚本中,exit语句是用来退出当前脚本的。也就是说,在Shell脚本中,只要碰到了exit语句,后续的程序就不再执行,而直接退出脚本。
②break语句,当程序执行到break语句时,会结束整个当前循环。而continue 语句也是结束循环的语句,不过continue 语句单次当前循环,而下次循环会继续。
③continue语句,continue也是结束流程控制的语句。如果在循环中,continue语句只会结束单次当前循环。