概述
既是一种应用程序 , 又是一种程序设计语言
从应用程序角度理解
概念:
交互式地解释、执行用户输入的命令,将用户的操作翻译成机器可以识别的语言,完成相应功能 . 称之为 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