shell脚本概述
Shell脚本是利用 shell 的功能所写的一个程序。这个程序是使用纯文本文件,将一些 shell 的语法与命令(含外部命令)写在里面,搭配正则表达式、管道命令与数据流重定向等功能
执行方式 bash test.sh source test.sh ./test.sh
shell变量
变量介绍
变量使用示例:
#在shell编程中通常使用全大写变量,方便识别
COUNT=1
#变量的调用:在变量前加$
echo $COUNT
#Linux Shell/bash从右向左赋值
Y=y
X=$Y
echo $X
#输出y
#使用unset命令删除变量的赋值
Z=hello
echo $Z
#输出hello
unset Z
echo $Z
变量取值
- 双引号:弱引用,允许通过$符号引用其他变量值,其中的变量引用会被替换为变量值
- 单引号:强引用,禁止引用其他变量值,$视为普通字符,其中的变量引用不会被替换为变量值,而保持源字符串
- 反撇号: 命令替换,提取命令执行后的输出结果,``和$(…)作用相同
数组的使用
echo a=(1 2 3 4 5)
echo $a #默认显示数组a的第一个元素
echo ${a[0]} #显示数组中第一个元素,以此类推
echo ${a[-1]} #显示数组中最后一个元素
echo ${a[*]} #和echo ${a[@]} 显示数组中所有元素
echo ${#a[@]} #显示数组中元素的个数
#显示数组中以起始元素为首的指定个数的元素(注意:这里起始元素id不能为负值
echo ${a[@]:起始元素id:元素个数}
unset a[n] #删除数组中的第n个元素
unset a #删除a这个数组
只读变量
- 使用readonly修饰
- 变量值不允许修改(重新赋值)的情况
- 无法使用 unset删除
- 最快方法重启
位置变量和预定义变量
- $0 与键入的命令行一样,包含脚本文件名
- $1,$2,……$9 ${10} 分别包含第一个到第十个命令行参数
- $# 包含命令行参数的个数
- $@ 包含所有命令行参数,"$@" 每个数据是单独的个体
- $* 包含所有命令行参数,"$*" 是一个整体
- $? 包含前一个命令的退出状态
- $$ 包含正在执行进程的ID号
常用环境变量
- $USER 表示用户名称
- $HOME 表示用户的宿主目录
- $LANG 表示语言和字符集
- $PWD 表示当前所在工作目录
- $PATH 表示可执行用户程序的默认路径
- export可以将变量指定为全局变量
shell语句(bash命令)
Shell 程序由零或多条shell语句构成。 shell语句包括三类: 说明性语句 功能性语句 结构性语句。
- 说明性语句 以#号开始到该行结束,不被解释执行
- 功能性语句
- read从标准输入读入一行, 并赋值给后面的变量
- read var 把读入的数据全部赋给var
- read var1 var2 var3 把读入行中的第一个单词(word)赋给var1, 第二个单词赋给var2, ……把其余所有的词赋给最后一个变量.
- 如果执行read语句时标准输入无数据, 则程序在此停留等侯, 直到数据的到来或被终止运行。
- 算术运算命令expr主要用于进行简单的整数运算
-
expr 12 + 5 \* 3 #输出27 expr 3 - 8 / 2 #输出-1 num=9 sum=`expr $num \* 6` echo $sum #输出54
- test命令可测试三种对象:字符串、整数、文件属性
- 每种测试对象都有若干测试操作符
-
#字符串测试 s1 = s2 #测试两个字符串的内容是否完全一样 s1 != s2 #测试两个字符串的内容是否有差异 -z s1 #测试s1 字符串的长度是否为0 -n s1 #测试s1 字符串的长度是否不为0 #整数测试 a -eq b #测试a 与b 是否相等 a -ne b #测试a 与b 是否不相等 a -gt b #测试a 是否大于b a -ge b #测试a 是否大于等于b a -lt b #测试a 是否小于b a -le b #测试a 是否小于等于b #文件测试 -e name #测试一个文件是否存在 -d name #测试name 是否为一个目录 -f name #测试name 是否为普通文件 -L name #测试name 是否为符号链接 -r name #测试name 文件是否存在且为可读 -w name #测试name 文件是否存在且为可写 -x name #测试name 文件是否存在且为可执行 -s name #测试name 文件是否存在且其长度不为0 f1 -nt f2 #测试文件f1 是否比文件f2 更新 f1 -ot f2 #测试文件f1 是否比文件f2 更旧
重要细节示例:
vi test.sh
#!/bin/bash 说明shell类型
echo "Hello world"
#赋值= 前后不能加空格
#数组定义
a=(1 2 3 4 5)
echo $a
echo ${a[*]}
echo ${a[@]}
echo ${#a[*]}
echo ${#a[@]}
a[2]=9
unset a[2]
unset a
#vi底行模式 :noh 取消高亮
readonly COUNT=3
#只读变量无法使用 unset 删除
echo $1
echo $#
echo $* (整体)
echo $@ (单个数据)
echo $?上一条命令的执行结果
echo $$
#从stdin输入时需要用空格隔开,不能用回车隔开
read val1 val2
#-s 输入不回显
#-t 规定输入的时间
#-p 指定输入的提示字符串
read -p "please input 2 num:" val1 val2
read -t 3 -p "please input 2 num:" val1 val2
read -s "please input 2 num:" val1 val2
#+前后要加空格,不加空格则当作一个字符串拼接
temp=`expr $val1 + $val2`
echo $temp
#*需要使用转移符\
temp=`expr $val1 \* $val2`
echo $temp
val1="123"
val2="123"
#使用test尽量加"",不加""有时可能出现异常
#test命令的返回函数状态码,0表示正常,非0表示异常
test "$val1" = "$val2"
echo $? #上一条命令的执行结果
test -z "$val1"
test -n "$val1"
结构性语句
主要包括: 条件测试语句(两路分支) 多路分支语句 循环语句 循环控制语句等
分支语句
单路分支语句:
#else可以省略不写
#如果执行的命令返回结果为0(没有问题) 则执行then后面的命令,否则执行else后面的命令
if 执行的命令
then 命令表
elif 执行的命令
then 命令表
else 命令表
fi
多路分支语句:
case 变量 in
表达式1)
若干命令
;;
表达式2)
若干命令
;;
*)
若干命令
;;
esac
循环语句
for 变量 in 表
do
若干命令
done
while 命令或表达式
do
命令表
done
重要细节例子:
#if [ -e $file ] 代替 if test -e $file
#空格不能随便删除
#例如test.sh
#!/bin/bash
read -p "input a filename:" file
if [ -f $file ]
then
echo "$file is a file"
elif [ -d $file ]
then
echo "$file is a dir"
fi
#!/bin/bash
#双分号;;只有在最后一项可以省略
read -p "input yes/no:" val
case $val in
yes | y)
echo "input yes"
;;
YES | Y)
echo "input YES"
;;
no)
echo "input no"
;;
*)
echo "other"
esac
#-a 与
#-o 或
# ! 非
if [ $val -gt 100 -o $val -lt 0 ]
if [ $val -gt 100 ] || [ $val -lt 0 ]
#!bin/bash
filename=`ls`
for file in $filename
do
echo "$file"
done
#!bin/bash
#$@和$*的区别
#for vals in "$@"
for vals in "$*"
do
echo "$vals"
done
#for((vals=0;vals<5;vals++))
for vals in 1 2 3 4 5
do
echo "$vals"
done
i=0
#while((i<5))
while [ $i -lt 5 ]
do
echo "$i"
i=`expr $i + 1`
done
函数
函数的定义,[]是可选项
- function name() {
- statements
- [return value]
- }
两种调用函数的区别
- 直接调用是在本地环境执行的,使用命令置换是在另一个环境下执行的,
- function_name [arg1 arg2 … ]
- value_name=`function_name [arg1 arg2 … ]`
变量的作用域
- 默认函数内定义的变量属于本环境的全局变量
- 使用local关键字可以声明为局部变量
一些例子:
#!/bin/bash
fuction fun(){
val=100
echo "$1"
return 0
}
echo `fun linuxx`
fun
$?
#函数内的变量默认 为全局变量
#使用local关键字说明局部变量
echo $val
#如果使用的是命令置换调用函数`fun`,则函数内部的变量不是局部变量