前言
shell编程也是属于一个C++程序员的基本功,由于是很久之前学的,很多细节在使用的时候都需要去查文档,于是最近趁着复习的时候总结了下在shell编程中常用的一些知识分享给大家。
系统调用
是操作系统提供给用户软件的接口。用户软件通过系统调用来使用操作系统提供的功能。
中断机制
中断的本质是处理器对外开放的实时受控接口。
1 shell的保存位置
cat /etc/shells
查看日期:data 显示时间, data +%s 显示时间戳
data +%y%m%d 按年月日显示日期
crontab 设置定时任务
2 如何运行脚本
bash 或者 sh [脚本的相对路径和绝对路径]
- 直接输入脚本的绝对路径或者相对路径(前提是拥有可执行权限)
- 在脚本前加
.
或者source
命令
3 变量
3.1 系统变量
类似于如下的变量,系统定义好的变量,可以使用 set
命令获取所有的系统变量。
echo "\$HOME" $HOME
echo "\$PWD" $PWD
echo "\$SHELL" $SHELL
echo "\$USER" $USER
3.2 用户自定义变量
- 自定义变量时直接使用
变量名=[变量值]
进行定义,等号左右不能有空格,如果值本身就有空格,就用引号引起来。 - 使用 export 将局部变量提升为全局变量,但是在子shell中更改变量的值后,父shell中的值不变
- 定义只读变量
readonly a=5
- 撤销定义的变量
unset a
3.3 特殊变量
- 使用
$n
来代表输入参数 $#
获取输入参数的个数$*
代表命令行中所有的参数,把所有参数看成一个整体$@
代表命令行中所有的参数,但是把所有参数区分对待
echo "==========for $*============="
for para in "$*"
do
echo $para
done
echo "==========for $@============="
for para in "$@"
do
echo $para
done
# 运行结果为 (如果对$*和$@ 不加引号他们没有区别)
==========for a b c d e f=============
a b c d e f
==========for a b c d e f=============
a
b
c
d
e
f
$?
最后一次执行命令的返回状态,如果值为0表示执行正确
4 运算符
$((运算式))
和$[运算式]
$((1+1))
$[1+1]
5 条件判断
-
[ condition ]
condition前后一定要有空格,条件非空即为true。 -
在使用
$?
来查看的时候,返回0代表true,1表示false。这是与正常编程语言相反的。 -
在shell中是没有
>, <
号的
-
还可以对文件的权限进行判断。例如:
[ -r 文件名 ]
判断对这个文件是否有读的权限 -
多条件判断:
&&
表示前面的一条命令执行成功时才执行后一条命令,||
表示上一条命令执行失败时才执行下一条命令。例如:[ $a -gt 0 ] && echo "$a >= 0" || echo "$a < 0"
输出的结果为:3 >= 0
-
短路与,短路或
[ $a -gt 0 ] && echo "$a >= 0" || echo "$a < 0"
# 这种方式利用的时短路与和短路或的方式
# 当使用短路与运算符时,如果第一个条件为假(即返回0),则整个表达式的结果为假,后面的条件将不会被执行。只有当第一个条件为真(即非零值)时,才会继续执行并判断后面的条件
# 当使用短路或运算符时,如果第一个条件为真(即非零值),则整个表达式的结果为真,后面的条件将不会被执行。只有当第一个条件为假(即返回0)时,才会继续执行并判断后面的条件。
6 流程控制
6.1 单分支控制
if [ condition ]; then
echo "我是程序"
fi
# 或者
if [ condition ]
then
echo "我是程序"
fi
6.2 多分支流程控制
echo "==========多分支==========="
if [ $b -lt 18 ];then
echo "未成年"
elif [ $b -ge 18 ] && [ $b -lt 40 ];then
echo "壮年"
else
echo "老年人"
fi
6.3 case 语句
注意事项:case的行尾必须加上 in
,每个模式匹配必须以 )
结尾,*)
表示默认匹配,每个匹配语句结束后要以 ;;
结尾
echo "=========case=============="
case $a in
"1")
echo "case 1"
;;
"2")
echo "case 2"
;;
*)
echo "others"
;;
esac
6.4 循环控制
for (( 初始值; 循环控制条件; 变量变化 ))
do
echo "执行程序"
done
第一种for的写法:
for (( c=1; c <= 10; c++ ))
do
echo "$c"
done
第二种for的写法, 类似于case ... in ...
for c in 1 2 3 4 5 6 7 8 9 10
也可以写成 for c in {1..100}
的形式,因为{1..100}
表示的就是一个序列,从1到100
echo "==========for 2============="
for c in 1 2 3 4 5 6 7 8 9 10
do
sum=$[ $sum + $c]
echo $sum
done
6.5 while循环
while [ 条件判断式 ]
do
程序
done
例如:
echo "===========while=============="
c=0
while [ $c -lt 10 ]
do
# sum=$[ $sum + $c ]
# c=$[ $c + 1 ]
let sum+=c
let c++
done
echo $sum
7 read 读取控制台的输入
read [选项] [参数]
-p 指定读取时的提示符
-t 指定读取时的等待时间,不加会一直等待
#!/bin/bash
echo "==========read============="
read -p "输入a " -t 1 a
read -p "输入b " -t 1 b
sum=$[$a+$b]
echo "a + b = $sum"
8 函数
8.1 系统函数
basename [string/pathname] [后缀]
会删除掉所有的前缀包括最后一个‘/’字符,然后将字符显示出来,后缀如果被指定,会将这个后缀去掉。
在使用函数的时候需要用命令替换符$(函数 参数)
括起来
echo "===========function=========="
name=$1_$(date +%s)
echo $name
dirname [string/pathname]
截取最后一个‘/’之前的路径
8.2 自定义函数
[function] funname [()]{
Action;
[return int;]
}
函数返回值只能通过 $?
来获得,可以用return来返回,如果不加,将以最后一条命令运行结果作为返回值。return 后跟数值n(0~255)。
在函数中形参的获取也是使用 $n
来获取
例如求两个数的和:
echo "=============add==============="
function ADD(){
sum=$[$1 + $2]
echo $sum;
}
read -p "a " a
read -p "b " b
sum=$(ADD $a $b)
echo "a + b = "$sum
9 正则表达式
^ 开头
$ 结尾
. 占一个字符
* 任意字符出现任意多次
[] 匹配某范围内的任一字符