shell脚本常用语法
Shell概述
shell的两层含义:
(1)应用程序(shell命令解释器)
交互式的解释、执行用户输入的命令,将用户的操作翻译成机器可以识别的语言,完成相应功能。
shell是用户和Linux内核之间的接口程序
用户在提示符下输入的命令都是由shell先解释然后传给Linux内核
它调用了系统内核的大部分功能来执行程序,并以并行的方式协调各个程序的运行。
Linux系统中提供了好多种不同的shell命令解释器,如sh、ash、bash等,一般使用bash作为默认解释器。
(2)程序设计语言(shell脚本)
定义了各种变量和参数,并提供了许多在高级语言中才具有的控制结构,包括循环和分支,完成类似于windows下批处理操作,简化我们对系统的管理与应用程序的部署。
帮助开发人员或系统管理员将复杂而反复的操作放在一个文件中,通过简单的一步执行操作完成相应任务,减轻负担。
shell脚本大体分为两类:
(1)系统进行调用
这类脚本无需用户调用,系统会在合适的时候调用,如:/etc/profile ,~/.bashrc
/etc/profile
此文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行,系统的公共环境变量在这里设置开启自启动的程序,一般也在这里设置。
~/.bashrc
用户自己的家目录中的.bashrc
登录时会自动调用,打开任意终端时也会自动调用
这个文件一般设置与个人用户有关的环境变量,如交叉编译器的路径等等
(2)用户编写需手动调用
总结:无论是系统调用还是手动调用,其语法规则都是一样的。
shell语法
1、定义开头:#!/bin/sh
含义:该脚本文件优先被bin文件夹下的sh去解析。如果无该语句则使用默认shell解析器(bash)
2、单个#表示注释
3、chmod +x test.sh ./test.sh增加可执行权限后执行
bash test.sh 直接指定使用bash解析test.sh
.(空格)test.sh(source(空格)test.sh) 使用当前shell读取解释test.sh
三种执行脚本的不同
./和bash执行过程基本一致,后者明确指定bash解释器去执行脚本,脚本中的指定解释器不起作用。前者首先检测#!,使用#!指定的解释器,如果没有使用默认的解释器。
用.去执行脚本不会启动新的shell,直接由当前的shell去解释执行脚本。
注意:如果是在windows下通过notepad++编辑的脚本程序需要用vi打开,在最后一行模式下执行:
set ff=unix
shell自定义变量
定义变量
变量名=变量值
如num=10(等号左右没有空格)
引用变量
$变量名
如:i=$num 把变量num的值付给变量i
显示变量
使用echo命令可以显示单个变量取值
echo $num
消除变量
使用unset命令清除变量
unset varname
变量的其他用法
read string
从键盘输入一个字符串赋给变量string
readonly var=100
定义一个只读变量,只能在定义时初始化,以后不能改变,不能被清除。
export var=300
使用export说明的变量,会被导出环境变量,其他shell均可使用
注意:此时必须使用source 2_var.sh 才生效
注意事项:
变量名只能包含英文字母、数字、下划线,不能以数字开头
例:
1_num=10 错误
num_1=10 正确
等号前后不能有空格,若变量中本身包含了空格,则整个字符串都要用双引号、单引号括起来。双引号内的特殊字符可以保有变量特性,但是单引号内的特殊字符则仅为一般字符。
例:
name=aa bb 错误
name=“aa bb” 正确
echo "$name is me" 输出aa bb is me
echo '$name is me' 输出 $name is me
shell环境变量
shell在开始执行时就已经定义了一些和系统的工作环境有关的变量,我们在shell中可以直接使用$name引用
定义:一般在~/.bashrc或/etc/profile文件中(系统自动调用的脚本)使用export设置,允许用户后来更改。传统上:所有环境变量均为大写。
显示环境变量
使用env命令可以查看所有的环境变量
消除环境变量
使用unset命令消除环境变量
常见环境变量
HOME:用于保存注册目录的完全路径名
PATH:用于保存用冒号分隔的目录路径名,shell将被PATH变量中给出的顺序搜索这些目录,找到的第一个与命令名称一致的可执行文件将被执行。
PATH=$HOME/bin:/bin:/usr/bin;export PATH
HOSTNAME:主机名
SHEL:默认的shell命令解析器
LOGNAME:此变量保存登录名
PWD:当前工作目录的绝对路径名
预设变量
$#:传给shell脚本参数的数量
$*:传给shell脚本参数的内容
$1、$2、$3、...$9:运行脚本时传递给其的参数,用空格隔开
$?:命令执行后返回的状态
"$?"用于检查上一个命令执行是否正确(在linux中,命令退出状态为0表示该命令正确)
$0:当前执行的进程名
$$:当前进程的进程号
"$$"变量最常见的用途是用作临时文件的名字以保证临时文件不会重复。
## 脚本
变量的特殊用法:"" " `` \ () {}
""(双引号):包含的变量会被解释
"(单引号):包含的变量会当做字符串解释
``(数字键1左面的反引号):反引号中的内容作为系统命令,并执行其内容,可以替换输出为一个变量 $ echo "today is `date`" 输出today is 2021年03月28日星期日20:29:30 CST
\(转义字符):同C语言 \n \t \r \a 等echo命令需加 -e 转义
(命令序列):由子shell来完成不影响当前shell中的变量
{命令序列}:在当前shell中执行,会影响当前变量
## 条件
测试语句
在写shell脚本时,经常遇到的问题就是判断字符串是否相等,可能还要检查文件状态或进行数字测试,只有这些测试完成才能做下一步动作。
test命令:用于测试字符串、文件状态和数字
test命令有两种格式:
test condition 或 [ condition ]
使用方括号时,要注意在条件两边加上空格
shell脚本中的条件测试如下:
文件测试、字符串测试、数字测试、复合测试
测试语句一般与后面讲的条件语句联合使用
文件测试:
测试文件状态的条件表达式
-e 是否存在
-d 是目录
-f 是文件
-r 可读
-w 可写
-x 可执行
-L 符号链接
-c 是否字符设备
-b 是否块设备
-s 文件非空
字符串测试
test str operator “str”
test “str1” str operator “str2”
[str operator “str”]
[“str1” str operator “str2”]
其中 str operator 可以是:
= :两个字符串相等
!= :两个字符串不相等
-z :空串
-n :非空串
数字测试
test num1 num operator num2
[ num1 num operator num2]
num operator 可以是:
-eq: 数值相等(equal)
-ne: 数值不相等(not equal)
-gt: 数1大于数2(greater than)
-ge: 数1大于等于数2(greater equal)
-le: 数1小于等于数2(less equal)
-lt: 数1小于数2(less than)
复合测试
命令执行控制:
&& :逻辑与
|| :逻辑或
同时搭配
-a :两个条件同时成立(and)
-o :两个条件任何一个成立(or)
!:相反状态
if [ $score -ge 50 -a $score -lt 60 ];then
echo "one zone"
elif [ $score -ge 60 -o $score -lt 50 ];then
echo "two zone"
else
echo "three zone"
fi
if [ !$score -ge 50];then
echo "ok"
else
echo "no"
fi
控制语句
if判断语句
if[条件1];then
执行第一条程序
elif[条件2];then
执行第二条程序
else
执行第三条程序
fi
if [ -f file ]; then
echo "yes file"
elif [ -r file ]; then
echo "yes read"
else
echo "no"
fi
case语句
case $变量名 in
"第一个变量内容")
程序一
;;
"第二个变量内容")
程序二
;;
*)
其他程序
exit1
esac
case $USER in
rich | barbara)
echo "Welcome, $USER"
echo "Please enjoy your visit";;
testing)
echo "Special testing account";;
jessica)
echo "Do not forget to log off when you're done";;
*)
echo "Sorry, you are not allowed here";;
esac
for循环
for((初始值;限制值;执行步阶))
do
程序段
done
for((i=1;i<10;i++))
do
echo "$i"
done
for var in con1 con2 con3 ...
do
程序段
done
for a in 1 2 3 4 5 6
do
echo "$a"
done
while循环
while[判断语句]
do
程序段
done
#!/bin/bash
i=1
sum=0
while [ $i -le 100 ];
do
let sum+=i
let i++
done
echo $sum
until循环
until[判断语句]
do
程序段
done
until与while相反,当判断语句成立时退出循环,否则继续循环
#!/bin/sh
var=10
until [ $var -gt 1 ]
do
echo $var
var=$(($var - 1))
done
exit 0
补充
break:允许跳出循环
continue:跳出此次循环,进行下一次循环