这里只是对shell脚本使用的一个简单介绍,实际上Shell所涉及的东西远远不止如此,但是这些内容能对Shell有一个基础的理解。
脚本解析器
shell常用的解析器主要是bash和sh,可以通过下面命令查看
[root@iZbp1buyhgwtrw6hrp2ugjZ ~]# cat /etc/shells /bin/sh /bin/bash /usr/bin/sh /usr/bin/bash可以通过下面的命令查看默认的解释器
[root@iZbp1buyhgwtrw6hrp2ugjZ ~]# echo $SHELL /bin/bashshell脚本是以sh为后缀的文件。文件内容就是需要具体执行的脚本命令。
创建脚本
在root目录创建一个名字为hello.sh的脚本
[root@iZbp1buyhgwtrw6hrp2ugjZ ~]# touch hello.sh [root@iZbp1buyhgwtrw6hrp2ugjZ ~]# vi hello.sh ## 文件内部添加内容,无需其他内容,执行脚本的时候会直接执行文件内部的语句 echo "helloworld"启动脚本
使用bash启动使用bash启动脚本需要在命令前添加bash语句
[root@iZbp1buyhgwtrw6hrp2ugjZ ~]# bash /root/hello.sh helloworld 直接输入脚本绝对路径执行脚本这种方式不需要添加sh或者bash命令。直接执行脚本
[root@iZbp1buyhgwtrw6hrp2ugjZ ~]# ./hello.sh helloworld++需要注意的++
直接只用./进行访问可能会遇见权限问题
[root@iZbp1buyhgwtrw6hrp2ugjZ ~]# ./hello.sh -bash: ./hello.sh: Permission denied此时需要添加权限
chmod 777 variable.sh我们可以直接通过key=value在linux中设置自己的变量。
设置变量的时候需要注意下面的问题:
变量名称可以由字母、数字和下划线组成,但是不能以数字开头变量设置对等号附近的空格敏感,所以在设置参数的时候等号两侧不能有空格变量默认的为字符类型,不能进行运算如果变量值中有空格,需要使用单引号或者双引号包裹如果变量值中存在其他变量需要使用双引号。声明一个变量
这种方式可以声明一个name的变量
echo "赋值新变量:设置变量name为dai" name=dai echo $name脚本输出
赋值新变量:设置变量name为dai dai修改一个变量
下面语句尝试修改name变量
echo "重新赋值:修改变量name为dai2" name=dai2 echo $name脚本输出
重新赋值:修改变量name为dai2 dai2删除一个变量
将name变量进行删除
echo "撤销变量:name" unset name echo $name脚本输出
撤销变量:name声明一个只读的变量
此时尝试删除此变量后此变量依旧可以正常输出
echo "声明只读的变量:name_read" readonly name_read="readonly" echo $name_read unset name_read echo $name_read脚本输出
声明只读的变量:name_read readonly readonly输出一个带变量的运算结果
尝试输出一个变量的运算结果,此时使用双引号可以正常输出,而单引号会将变量作为字符串输出
echo "双引号中识别变量" echo "hello $name_read" echo "单引号中识别变量" echo 'hello $name_read'脚本输出
双引号中识别变量 hello readonly 单引号中识别变量 hello $name_read将命令结果赋值给变量
此方法可以将linux中命令的结果赋值给变量,下面使用命令或者$(命令)都是可以的
echo "将一个命令结果给其他变量方法1" name1=`date` echo $name1 echo "将一个命令结果给其他变量方法2" name2=$(date) echo $name2脚本输出
将一个命令结果给其他变量方法1 Wed Oct 7 13:33:16 CST 2020 将一个命令结果给其他变量方法2 Wed Oct 7 13:33:16 CST 2020脚本中声明变量在控制台中尝试获取
现在最开始的hello.sh修改成下面样子,对一个this_date变量进行赋值。
echo "输出this_date" echo $this_date this_date=`date` echo "设置完后输出this_date" echo $this_date此时执行后可以看到结果已经声明的变量内容。但是后续尝试在控制台中获取此变量却没有获取到结果,可以发现脚本中声明的变量并没有传递到控制台中
[root@iZbp1buyhgwtrw6hrp2ugjZ ~]# ./hello.sh 输出this_date 设置完后输出this_date Wed Oct 7 13:48:39 CST 2020 [root@iZbp1buyhgwtrw6hrp2ugjZ ~]# echo $this_date [root@iZbp1buyhgwtrw6hrp2ugjZ ~]#在控制台中声明变量,脚本中尝试获取
此时可以发现在外部声明的变量在脚本中同样无法获取。
[root@iZbp1buyhgwtrw6hrp2ugjZ ~]# this_date=`date` [root@iZbp1buyhgwtrw6hrp2ugjZ ~]# echo $this_date Wed Oct 7 13:53:06 CST 2020 [root@iZbp1buyhgwtrw6hrp2ugjZ ~]# ./hello.sh 输出this_date 设置完后输出this_date Wed Oct 7 13:53:23 CST 2020 [root@iZbp1buyhgwtrw6hrp2ugjZ ~]#这是因为上面脚本执行是当前shell中打开一个子shell来执行脚本内容,当脚本内容结束,则子shell关闭,回到父shell中。如在子shell中设置的当前变量,不做特殊通道处理的话,父shell是不可见的。
将自定义变量设置为全局变量
我们可以将自定义变量设置为全局变量,这边其他的shell脚本也可以使用。
这样操作需要将之前的脚本最后添加下面内容:
export this_date此时再进行操作就可以获得结果
[root@iZbp1buyhgwtrw6hrp2ugjZ ~]# ./hello.sh 输出this_date 设置完后输出this_date Wed Oct 7 13:58:17 CST 2020 [root@iZbp1buyhgwtrw6hrp2ugjZ ~]# echo $this_date Wed Oct 7 13:53:06 CST 2020当然也可以尝试修改/etc/profile文件通过添加export key=value来设置变量为系统变量。不过不要忘了最后执行source /etc/profile命令
当脚本存在输入参数的时候,可以使用 n 、 n、 n、#、 ∗ 、 *、 ∗、@来获取参数的内容
$n
可以用$n来表示哪个参数。 0 : 为 脚 本 名 称 ; 1 − n 表 示 第 几 个 参 数 , 其 中 1 − 9 表 示 为 0:为脚本名称;1-n表示第几个参数,其中1-9表示为 0:为脚本名称;1−n表示第几个参数,其中1−9表示为n,10以上需要包裹大括号${n}
$#
用来获取参数个数
$*
命令行中所有的参数,$*把所有的参数看成一个整体
$@
代表命令行中所有的参数,$@把每个参数区分对待
实例
现在创建一个param.sh的脚本内容如下
echo "$0 $1 $2" echo $# echo $* echo $@其输出内容
[root@iZbp1buyhgwtrw6hrp2ugjZ ~]# ./param.sh param1 param2 ./param.sh param1 param2 2 param1 param2 param1 param2$?变量可以证明上一个命令是否正确执行。如果为0在证明执行正确,否则则证明执行出现了问题
[root@iZbp1buyhgwtrw6hrp2ugjZ ~]# ./param.sh param1 param2 ./param.sh param1 param2 2 param1 param2 param1 param2 [root@iZbp1buyhgwtrw6hrp2ugjZ ~]# echo $? 0 [root@iZbp1buyhgwtrw6hrp2ugjZ ~]# asdad -bash: asdad: command not found [root@iZbp1buyhgwtrw6hrp2ugjZ ~]# echo $? 127计算的语法
*号需要转义为*运算指的都是整数的运算运算以expr开始,符号间需要空格运算符号
符号作用+加-减*乘/除%取余嵌套运算
当存在(a + b) * C这种多个运算嵌套的时候下面两种方式都能实现结果
[root@iZbp1buyhgwtrw6hrp2ugjZ ~]# expr `expr 1 + 2` \* 3 9 [root@iZbp1buyhgwtrw6hrp2ugjZ ~]# rest=$[(1+2)*3] [root@iZbp1buyhgwtrw6hrp2ugjZ ~]# echo $rest 9判断语句的语法
## 注意前后要有空格 [ 判断语句 ]判断条件
符号作用=字符串比较-lt小于-le小于等于-eq等于-gt大于-ge大于等于-ne不等于-r有读的权限-w有写的权限-x有执行的权限-f文件存在并且是一个常规的文件-e文件存在-d文件存在并是一个目录-s文件存在且不为空-L文件存在且是一个链接使用示例
使用下面方式可以实现结果的输出
[root@iZbp1buyhgwtrw6hrp2ugjZ ~]# [ 23 -ge 26 ] && echo ture || echo false false [root@iZbp1buyhgwtrw6hrp2ugjZ ~]# [ -w hello.sh ] && echo ture || echo false ture [root@iZbp1buyhgwtrw6hrp2ugjZ ~]# [ -d hello.sh ] && echo ture || echo false falseshell 中的if流程格式为下面格式,最后以fi结束。课条件判断一样[]和条件公式需要空格分隔,而if后面也需要空格分隔
if [ 条件判断式 ] then 逻辑1 elif 条件判断式 then 逻辑2 else 逻辑3 fi示例
创建下面的一个脚本用来表示if的使用方式
if [ $1 -eq 1 ] ; then echo "输入逻辑1" elif [ $1 -eq 2 ] ; then echo "输入逻辑2" elif [ $1 -eq 3 ] ; then echo "输入逻辑3" else echo "未知逻辑" fi返回内容
[root@iZbp1buyhgwtrw6hrp2ugjZ ~]# ./test.sh 1 输入逻辑1 [root@iZbp1buyhgwtrw6hrp2ugjZ ~]# ./test.sh 2 输入逻辑2 [root@iZbp1buyhgwtrw6hrp2ugjZ ~]# ./test.sh 3 输入逻辑3 [root@iZbp1buyhgwtrw6hrp2ugjZ ~]# ./test.sh 7 未知逻辑++需要注意++
和上面使用简单逻辑的示例不同,这里涉及多行判断,此时可能会遇见换行符的问题,
通过vim编辑脚本,在命令行模式下输入:set ff如果结果为fileformat=dos则需要手动输入置:set ff=unix来设置文件对应系统
基本语法
case逻辑以case开始以esac结束
case $变量 in 值1) 程序1 ;; 值2) 程序2 ;; 值3) 程序3 ;; *) 其他 ;; esac示例
将上面if的逻辑改为case后脚本内容如下
case $1 in 1) echo "case输入逻辑1" ;; 2) echo "case输入逻辑2" ;; 3) echo "case输入逻辑3" ;; *) echo "case未知逻辑" ;; esac输出内容如下
[root@iZbp1buyhgwtrw6hrp2ugjZ ~]# ./test.sh 8 case未知逻辑 [root@iZbp1buyhgwtrw6hrp2ugjZ ~]# ./test.sh 1 case输入逻辑1基本语法
for (( 初始值;循环控制条件;变量变化 )) do 程序 done示例
上面内容可以使用一个简单的i循环来实现其效果
for((i=0;i<=10;i++)) do echo $i done最终输出内容
[root@iZbp1buyhgwtrw6hrp2ugjZ ~]# ./test.sh 0 1 2 3 4 5 6 7 8 9 10for 还能实现一种类似foreach的语法
for (变量 in 值1 值2 值3); do 程序; done示例
将上面语法改造下,用来循环输入参数
for i in $* do echo $i done++注意++
使用 for i in "$*"的时候整个参数会被看成一个整体,而只循环1次
执行后结果
[root@iZbp1buyhgwtrw6hrp2ugjZ ~]# ./test.sh 1 3 5 6 1 3 5 6基础语法
# 第一种 while [ 条件判断式 ] do 程序 done # 第二种 while((表达式)) do 程序 done示例
将上面的i循环改造为while格式
i=0 while [ $i -le 10 ] do echo $i i=$[$i+1] done最终输出的内容和使用i循环是一致的
[root@iZbp1buyhgwtrw6hrp2ugjZ ~]# ./test.sh 0 1 2 3 4 5 6 7 8 9 10shell中我们可以使用函数来实现一些复杂的逻辑,这里只介绍自定义函数的内容
++注意内容++
函数需要提前声明,shell脚本是逐行运行。不会像其它语言一样先编译。函数返回值,只能通过$?系统变量获得函数声明的格式
function funname() { Action; [return int;] }示例
创建一个汇总输入参数和的函数
sum_param=0 function rest() { for i in $* do echo $i sum_param=$[$sum_param + $i] done } rest $* echo "输入参数和为:$sum_param"最终返回结果
[root@iZbp1buyhgwtrw6hrp2ugjZ ~]# ./test.sh 2 4 5 2 4 5 11shell提供的输入语法
read -t 等待时间 -p "提示语句" 变量名称示例
read -t 5 -p "请在5秒钟内输入一个数字" NUM echo "输入的数字为:$NUM"脚本执行的结果
[root@iZbp1buyhgwtrw6hrp2ugjZ ~]# ./test.sh 请在5秒钟内输入一个数字8 输入的数字为:8 [root@iZbp1buyhgwtrw6hrp2ugjZ ~]#个人水平有限,上面的内容可能存在没有描述清楚或者错误的地方,假如开发同学发现了,请及时告知,我会第一时间修改相关内容。假如我的这篇内容对你有任何帮助的话,麻烦给我点一个赞。你的点赞就是我前进的动力
