Shell编程
特殊变量
| 符号 | 描述 |
|---|---|
| $0 | 当前程式的名字 |
| $n | 参数 |
| $* | 所有参数 |
| $# | 参数个数 |
| $$ | 当前程式的PID |
| $# | 参数个数 |
Shell编程规范
- 赋值
=左右不加空格 - 条件判断
[ 值1 判断 值2 ]两端空格必须加
Shell配置文件加载顺序
- 所有
xxx.sh文件执行前都会读取/etc/profile或者/etc/bashrc(Ubuntu)文件
- 图形界面登录成功后打开终端先读取
/etc/bashrc再读取~/.bashrc- 图形界面时先读取
/etc/bashrc再读取~/.profile~/.profile:3和6均不存在时读取该文件
- 文本界面时先读取
~/.profile再读取/etc/profile和~/.bash_logout~/.bash_profile~/.bashrc:当bash以non-login形式执行时读取~/.bash_logout:bash注销的时候读取~/.bash_login:bash登录的时候读取
前后台作业控制
- fg %n: 将进程n切换到前台运行
- bg %n: 将进程n切换到后台运行
- kill -9 %n: 杀死进程n
- jobs:查看所有进程
输入输出重定向
| 文件描述符 | 文件名 | 类型 | 硬件 |
|---|---|---|---|
| 0 | stdin | 标准输入文件 | 键盘 |
| 1 | stdout | 标准输出文件 | 显示器 |
| 2 | stderr | 标准错误输出文件 | 显示器 |
command > file以覆盖的方式将正确结果输出到文件command >> file以追加的方式将正确结果输出到文件command 2> file以覆盖的方式将错误结果输出到文件command 2>> file以覆盖的方式将错误结果输出到文件command > file 2>&1不分正确和错误输出所有到文件command &> file不分正确和错误输出所有到文件command > file1 2> file2分别输出正确和错误结果到不同的文件
wc -l << ENDD
> 1
> 222
> 3334334
> ENDD
3
command | tee file将结果输出的同时保存到文件command1 | command2将1的结果作为2的输入输出
# 字体颜色:30m-37m 黑、红、绿、黄、蓝、紫、青、白 echo -e "\033[30m string \033[0m" # 背景颜色:40-47 黑、红、绿、黄、蓝、紫、青、白 echo -e "\033[41;37m string \033[0m" # 获取var的字符串长度 echo ${#var} # 运算:+(加) -(减) \*(乘) /(除) echo $[5**2] #等同于expr 5**2 # 格式化输出 scale(小数位数) ibase/obase(进制) echo "scale=2;4/3" |bc # 索引和切片 var = hello,world! echo ${var5} #结果:hello echo ${var:5} #结果:,world! # 匹配输出 var = hello,world! echo ${var#*o} #结果:,world! echo ${var##*o} #结果:rld! echo ${test/o/O} #结果:hellO,world! echo ${test//o/O} #结果:hellO,wOrld!Shell变量分类
- 自定义变量
- 定义:
- 直接赋值:
var=value - 间接赋值:
var='pwd'
- 直接赋值:
- 查看:
echo $var - 删除:
unset var(仅在当前控制台有效)
- 定义:
- 环境变量
- 定义:
- 直接定义:
export var=value - 转义定义:
export var(var为自定义变量)
- 直接定义:
- 定义:
- 位置变量
- 命令的参数按位置排序依次为
$1-~ - 所有参数为
$* - 参数个数为
$# - 进程PID为`$$
- 命令的参数按位置排序依次为
Read输入
计算和
read -p "请输入NUM1:" num1 read -p "请输入NUM2:" num2 echo -e "\033[31m $num1+$num2=$[$num1+$num2] \033[0m" read -u n #读取一次文件描述符n的内容,读取不到则停止
结果:
请输入NUM1:32
请输入NUM2:12
32+12=44
FOR循环
seq a b 用于产生a到b之间的所有整数(批量创建目录)
for i in {1..10} #等同于 for i in $(seq 1 10) do mkdir -p /home/calong/loop/demo$i done
遍历数组类变量(计算每个文件夹的大小)
DIR="/var" cd $DIR for i in $(ls $DIR) do [ -d $i ] && du -sh $i done
While循环
while循环读取文件内容
while read demo do echo $demo done < /home/calong/data/demo-3.txt
计算1-100以内的和
declare -i num=1 declare -i sum=0 while ((num<=100)) do let sum+=num let num++ done echo "和为:$sum"
Until循环
计算1-100以内的和
declare -i num=1 declare -i sum=0 until ((num>100)) do let sum+=num let num++ done echo "和为:$sum"
循环控制
break continue shift exit
while [ $# -gt 0 ] do echo $* shift done运行结果
bash demo-6.sh a b c d e f a b c d e f b c d e f c d e f d e f e f f
流程控制
符号说明
(())数值比较,运算,C语言[[]]条件测试,支持正则$(())和$[]整数运算$()命令替换,将结果作为变量进行替换,错误输出不能替换${}Shell中的变量原型,限定变量名称的范围,支持通配符
&&并且:前者成功再执行后者,否则不执行后者||或者:前者执行失败时会执行后者,前者执行成功则不执行后者
文件测试表达式
| 命令 | 描述 |
|---|---|
| -d 文件 | 文件存在且为目录则为真 |
| -f 文件 | 文件存在且为普通文件则为真 |
| -e 文件 | 文件存在则为真 |
| -s 文件 | 文件存在且大小不为0则为真 |
| -r 文件 | 文件存在且可读则为真 |
| -w 文件 | 文件存在且可写则为真 |
| -x 文件 | 文件存在且可执行则为真 |
| -L 文件 | 文件存在且为链接则为真 |
| 文件1 -nt 文件2 | 文件1比文件2新则为真 |
| 文件1 -ot 文件2 | 文件1比文件2旧则为真 |
字符串测试表达式
| 命令 | 参数 | 描述 |
|---|---|---|
| -z | string | 字符串长度为0则为真 |
| -n | string | 字符串长度大于0则为真 |
| sl | string | 字符串不为空则为真 |
| = | string | 字符串相等则为真 |
| != | string | 字符串不相等则为真 |
| < | string1 string2 | 字符串1按字典排序在字符串2之前则为真 |
| > | string1 string2 | 字符串1按字典排序在字符串2之后则为真 |
整数操作符
| 命令 | 描述 |
|---|---|
| -eq | 等于 |
| -nq | 不等于 |
| -gt | 大于 |
| -ge | 大于等于 |
| -lt | 小于 |
| -le | 小于等于 |
If判断
单分支if
if [ $USER=='root' ];then echo "当前为root用户" fi
双分支if
if [ $USER=='root' ];then echo "当前为root用户" else echo "当前为普通用户" fi
多分支if
read -p "请输入数字:" num if (( $num==0 ));then echo "零" elif (( $num>0 ));then echo "正数" elif (( $num<0 ));then echo "负数" else echo "不是数字" fi
case分支
read -p "请输入第几天:" day case $day in 1) echo "工作日" ;; 2) echo "工作日" ;; 3) echo "工作日" ;; 4) echo "工作日" ;; 5) echo "工作日" ;; 6) echo "周末" ;; 7) echo "周末" ;; *) echo "未知日期" ;; esac
数组
定义方式
- array=(1 2 3)
- array=([0]=1 [1]=2 [2]=3)
- array[0]=1;array[1]=2;array[2]=3
- array=$(·ls /·)
遍历数组
echo ${array[@]}
数组中常用的变量
- 获取数组所有元素
${array[*]}和${array[@]}- 获取数组的元素个数
${#array[*]}和${#array[@]}- 获取指定下标的元素`${array[0]}
- 从下标x截取长度为y的数组
${array[@]: x: y}- 从下标x至末尾截取的数组
${array[@]:x}- 用new替换数组中的值old
${array[@]/old/new}
联合数组
声明
declare -A assArray assArray=([name]=Tom [age]=18 [sex]=男)
输出
echo ${assArray[@]} #输出所有元素 echo ${assArray[name]} #输出指定元素 echo ${#assArray[@]} #输出元素个数
遍历
declare -A assArray assArray=([name]=Tom [age]=18 [sex]=男) for key in ${!assArray[@]} do echo "${key} => ${assArray[$key]}" done
并发
command #普通命令
{
command #开启进程执行命令
}&
wait #等待线程结束
command
并发控制
PRONUM=10 tmpfile="$$.fifo" #生成临时管道文件 mkfifo $tmpfile exec 6<>$tmpfile #以读写的方式生成文件标识符6 rm $tmpfile for ((i=0;i<$PRONUM;i++)) do echo >&6 #初始化线程 done for i in {1..100} do read -u 6 { ...... #需要并行的代码 echo >&8 #还回一条记录 }& done wait exec 8>&- #关闭文件描述符
正则表达式
| 字符 | 含义 |
|---|---|
| . | 匹配任意单个字符 |
| ^ | 匹配行首 |
| $ | 匹配行尾 |
| + | 匹配前面正则表达式的1个或多个实例 |
| ? | 匹配前面正则表达式的0个或1个实例 |
| […] | 匹配范围,例如[a-z]/[0-9]/[a-z0-9] |
本作品采用《CC 协议》,转载必须注明作者和本文链接
关于 LearnKu
推荐文章: