概述
既是一种应用程序,又是一种程序设计语言
从应用程序角度理解
概念:
交互式地解释、执行用户输入的命令,将用户的操作翻译成机器可以识别的语言,完成相应功能.称之为 shell 命令解析器
作用:
shell是用户和 Linux 内核之间的接口程序
注意:
Linux 系统中提供了好几种不同的 shell命令解释器,如 sh、ash、bash 等。一般默认使用 bash 作为默认的解释器。我们后面编写的 shell脚本,都是由上述 shell命令解释器解释执行的。查看默认Shell命令解析器的命令为:echo $SHELL
从程序设计语言角度理解
概念:
它定义了各种变量和参数,并提供了许多在高级语言中才具有的控制结构,包括循环,分支,函数,完成类似于 windows 下批处理操作,简化我们对系统的管理与应用程序的部署称之为 shell 脚本
作用:
提高操作效率
注意:
shell脚本是一种脚本语言,我们只需使用任意文本编辑器,按照语法编写相应程序,增加可执行权限,即可在安装 shell命令解释器的环境下执行增加可执行权限命令:chmod +x 文件名
分类
系统调用
这类脚本无需用户调用,系统会在合适的时候调用,如:/etc/profile、~/.bashrc等/etc/profile:启动时调用~/.bashrc

用户编写,需要手动调用的
代码:#!/bin/bashecho "hello shell"增加可执行权限运行
注意
无论是系统调用的还是需要我们自己调用的,其语法规则都一样
语法
#!
用来声明脚本由什么shell解释,否则使用默认shell如:#!/bin/bash:说明脚本使用bash解释
#
注释
如
#!/bin/bash#这是shell注释#echo "hello"
执行
方式1
./shell文件名
这种方式先检测执行的文件中是否存在指定的shell命令解析器,如果存在使用指定的,如果不存在使用默认的开启子shell,由子shell执行
方式2
shell命令解析器名称 shell文件名
这种方式不会检测文件中是否存在指定的shell命令解析器,使用执行命令前指定的
shell解析器开启子shell,由子shell执行
方式3
source shell文件名或. shell文件名
这种方式不会开启子shell,直接由当前的 shell去解释执行脚本
注意
创建文件时:如果是在windows中创建编写的Shell脚本文件,拖拽到Liunx下无法运行,因为Windows与Liunx下\表示的含义不同,所以导致程序无法被识别解决方案1:在Liunx中使用vim编辑器,在最后一行模式输入 set ff=unix解决方案2:在Linux中安装dos2unix,使用dos2unix转换步骤:1,命令行输入:sudo apt-age install dos2unix2,命令行输入:dos2unix 文件地址
第一个shell脚本
步骤:1,创建一个文件2,指定解析器#!/bin/bash3,编写代码liunx命令4,保存5,增加权限chmod +x 文件名6,执行
变量
作用
临时记录一个值可以被改变的数据
分类
系统变量使用env查看注意:=左边为变量名等号右边为变量值自定义变量
变量的定义与初始化
变量名=值
注意:等号两边不能有空格此时所有的值都是字符串
变量的修改
变量名=值
注意:此时变量已经被定义
变量的取值
$变量名
注意:如果变量不存在返回空
撤销变量
unset 变量名
声明变量只读变量
readonly 变量名=值注意:值不能被修改
导出变量
export 变量名
作用:导出变量,导出给父shell
declare -i :将变量强制转换为数字
declare -i 变量名
注意
子shell可以访问父shell的变量父shell不能访问子shell的变量
预设变量
$#:传给 shell 脚本参数的数量
$*:传给 shell 脚本参数的内容$1、$2、$3、...、$9:运行脚本时传递给其的参数,用空格隔开$?:命令执行后返回的状态"$?"用于检查上一个命令执行是否正确(在 Linux 中,命令退出状态为 0 表示该命令正确执行,任何非 0 值表示命令出错)。$0:当前执行的进程名$$:当前进程的进程号"$$"变量最常见的用途是用作临时文件的名字以保证临时文件不会重复
示例
#/bin/bashecho $#echo $*echo $1echo $2echo $3argc=$#argv=$*echo $argcecho $argvcd ./a#返回上一个命令的状态,0正确执行,非0执行错误echo $?echo $0ps -eecho $$
脚本变量的特殊用法
"":包含的变量会被解释
'':包含的变量会作为字符串处理``:反引号中的内容作为系统命令,并执行其内容,可以替换输出为一个变量\:同c语言\n \t \r \a等echo命令需加-e转义(bash解析器需求)( 命令 ):由子shell来完成,不影响当前shell中的变量,命令前后必须有空格{ 命令 }:在当前shell中执行,会影响当前变量,命令前后必须有空格
示例
#!/bin/bashecho dateecho "date"echo 'date'echo `date`num=10;echo "$num"echo '$numecho "123\n456"echo -e "123\n456"data=1#开启子shell(#子shell可以访问父shell的变量data=100echo 子:$data)#父shell不能访问子shell的变量,顾父shell的变量并没有被修改echo 父:$data#当前shell中{data=100echo {}中:$data}echo {}外:$data
输入
语法
read 变量名或read -p 提示内容 变量名
示例
#!/bin/bashread -p 请输入要压缩的文件路径 filename# echo $filenameread -p 请输入压缩包名称 nametar -jcvf $name $filenameecho "OVER"
条件测试语句
语法
语法1:test 条件
语法2:[ 条件 ]注意:括号中有空格
文件测试
-e 是否存在-d 是否为目录-f 是否为文件-r 是否可读-w 是否可写-x 是否可执行-L 是否连接-c 是否字符设备-b 是否块设备-s 文件非空
示例
#!/bin/bash
#-e判断文件是否存在# test -e 13_shell.sh[ -e 10_shell.sh ]echo $?# -d 是否为目录[ -d / ]echo $?# -f 是否为文件[ -f / ]echo $?# -r 是否可读[ -r 00_shell ]echo $?# -w 是否可写[ -w 00_shell ]echo $?# -x 是否可执行[ -x 00_shell ]echo $?# -L 是否连接[ -L 00_shell ]echo $?# -c 是否字符设备[ -c 00_shell ]echo $?# -b 是否块设备[ -b 00_shell ]echo $?# -s 文件非空[ -s 00_shell ]echo $?
字符串测试
= 两个字符串相等
!= 两个字符串不相等-z 空串-n 非空串注意:= !=前后要有空格
示例
#!/bin/bash# = 两个字符串相等# != 两个字符串不相等# -z 空串# -n 非空串# 注意:= !=前后要有空格str01=abcstr02=abcstr03=ABCtest $str01 = $str02echo $?test $str01 != $str02echo $?test -z $str01echo $?test -n $str01echo $?
数值测试
-eq 数值相等
-ne 数值不相等-gt 数 1 大于数 2-ge 数 1 大于等于数 2-le 数 1 小于等于数 2-lt 数 1 小于数 2
示例
#!/bin/bashnum01=10num02=10# -eq 数值相等[ $num01 -eq $num02 ]echo $?# -ne 数值不相等[ $num01 -ne $num02 ]echo $?# -gt 数 1 大于数 2[ $num01 -gt $num02 ]echo $?# -ge 数 1 大于等于数 2[ $num01 -ge $num02 ]echo $?# -le 数 1 小于等于数 2# -lt 数 1 小于数 2#${num:-val} 如果num存在,返回num,否则返回valecho ${x:-10}#${num:=val} 如果num存在,返回num,否则返回val,并将val赋值给numecho ${y:=10}echo $y
复合测试
&&:
command1 && command2&&左边命令(command1)执行成功(即返回 0)shell 才执行&&右边的命令(command2)||command1 || command2||左边的命令(command1)未执行成功(即返回非 0)shell 才执行||右边的命令(command2)
示例
#!/bin/bash
n01=10n02=100n03=1000[ $n02 -gt $n01 ] && [ $n03 -gt $n01 ]echo $?
多重条件
-a:与-o:或!:非
示例
#!/bin/bash#输入文件路径判断文件是否可读可写可执行echo 请输入文件路径read filename[ -r $filename -a -w $filename -a -x $filename ]echo $filename 是否可读可写可执行: $?[ ! -x $filename ]echo $filename 是否不可执行: $?
if语句
语法
if [ 条件1 ];then
执行第1段程序elif [ 条件2 ];then执行第2段程序elif [ 条件3 ];then执行第3段程序...else执行第n段程序fi
示例
#!/bin/bash
read -p 请输入年龄 age# if [ $age -ge 18 ];then# echo 成年人# else# echo 未成年# fiif [ $age -ge 150 -o $age -le 0 ];thenecho 建国后不需成精elif [ $age -ge 100 ];thenecho 百岁老人elif [ $age -ge 70 ];thenecho 老人家elif [ $age -ge 40 ];thenecho 中年人elif [ $age -ge 18 ];thenecho 青少年elseecho 未成年fi
case语句
语法
case $变量名 in
"值1")语句1;;"值2")语句2;;*)语句3;;esac扩展:exit 1 #退出shell
示例
#!/bin/bashnum=12case $num in1)echo 等于1;;2)echo 等于2;;*)echo 不等于1,2;;esac
for语句
语法1
for (( 初始值; 限制值; 执行步阶 ))do程序段done
示例
#!/bin/bash
# for (( 初始值; 限制值; 执行步阶 ))# do# 程序段# donedeclare -i sum=0declare -i i=0for (( i = 0; i <= 100; i++ ))dosum=$sum+$idoneecho $sum
语法2
for var in con1 con2 con3 ...
do程序段done
示例
#!/bin/bash
# for v in 123 456 abc# do# echo $v# donefor v in `ls`doecho $vdone
while语句
语法
while [ 条件 ]
do程序段done
示例
#!/bin/bash
declare -i i=0while [ $i -le 100 ]doecho $ii=$i+1done
扩展
#!/bin/bash# 变量名=$(( 值1 + 值2 ))n01=10n02=2n03=$(( $n01 + $n02 ))echo $n03# 变量名=$(( 值1 - 值2 ))n04=$(( $n01 - $n02 ))echo $n04# 变量名=$(( 值1 * 值2 ))# 变量名=$(( 值1 / 值2 ))# 变量名=$(( 值1 % 值2 ))# 变量名=$(( 变量名-- ))# n05=$(( n01-- ))# echo $n05# echo $n01# 变量名=$(( --变量名 ))n05=$(( --n01 ))echo $n05echo $n01# 变量名=$(( 变量名++ ))# 变量名=$(( ++变量名 ))# 变量名=$(( -10 > 1 ? 10 : 1 ))n06=$(( -10 > 1 ? 10 : 1 ))echo $n06
until语句
语法
until [ 条件 ]do程序段done注意:当条件表达式为假执行循环体中的代码,如果为真,结束循环
示例
#!/bin/bashi=0until [ $i -ge 10 ]doi=$(( ++i ))echo $idone
函数
定义
语法1函数名(){程序段}语法2function 函数名(){程序段}
调用
函数名 参数1 参数2...
示例
#!/bin/bash#函数的定义1#函数名(){#}method(){echo 自定义函数被执行}#函数的调用:函数名 参数1 参数2 ...method#函数的定义2#function 函数名(){#}function method02(){echo 自定义函数2被执行}method02add(){num=$(( $1+$2 ))return $num}add 2 21echo $?
练习
完成以下任务:
判断用户家目录下(~)下面有没有一个叫 test 的文件夹如果没有,提示按 y 创建并进入此文件夹,按 n 退出如果有,直接进入,提示请输入一个字符串,并按此字符串创建一个文件,如果此文件已存在,提示重新输入,重复三次自动退出,不存在创建完毕,退出
#!/bin/bash
# 完成以下任务:
# 判断用户家目录下(~)下面有没有一个叫 test 的文件夹
# 如果没有,提示按 y 创建并进入此文件夹,按 n 退出
# 如果有,直接进入,提示请输入一个字符串,并按此字符串创建一个文件,如果此
# 文件已存在,提示重新输入,重复三次自动退出,不存在创建完毕,退出
if [ ! -e ~/test -a ! -d ~/test ];then
echo 按y键创建该文件夹
read tag
if [ $tag = y -o $tag = Y ];then
mkdir ~/test
elif [ $tag = n -o $tag = N ];then
exit 1
fi
fi
cd ~/test
read -p 请输入新建的文件名 filename
#默认文件不存在
flag=1
declare -i i=0
for (( i=0; i < 2; i++ ))
do
if [ -e $filename -a -f $filename ];then
echo 文件存在,请重新输入文件名
flag=0
read filename
else
flag=1
break
fi
done
if [ $flag = 1 ];then
touch $filename
echo 创建成功
else
echo 输入的文件名都存在
fi
echo OVER