Linux的shell编程学习

shell基本编程与trap的命令,用户在线例子

先写一个脚本

先写一个Shell脚本文件
  1 #!/bin/bash    #脚本默认开头                                                                              
  2 
  3 echo "hello!"
默认没有执行权限x,可通过chmod添加
$ sudo chmod +x T01.sh    #添加执行权限
$ bash T01.sh             #通过bash执行脚本
$ ./T01.sh                #直接执行脚本

一、变量

  • 局部变量:仅限于命令行,或Shell脚本文件中。
  • 全局变量:Shell进程及其所有子进程
  • 可以使用export内置命令将局部变量设置为全局变量 ,用法:export 局部变量名
    在这里插入图片描述
  • 变量三种:普通变量(用户自定义的变量)、系统预定义的环境变量(PATH)和命令行变量(KaTeX parse error: Expected 'EOF', got '#' at position 1: #̲、*)
  • 给变量赋值的时候等号两边不能有空格,引用变量需要在前面加$即可。
  • 环境变量的设置(每个环境变量都用大写字母表示)
$ myname="hello I am xiaona!"    #普通变量赋值
$ echo $myname                   #引用普通变量
$ env                            #查看系统环境变量
$ export PATH=dir/               #修改PATH的变量为dir/
$ export PATH=$PATH:dir/         #PATH再增加一个目录(增加新的值需要使用:分隔开,不该便原有的值)
$ source ~/.bashrc               #使刚添加的环境变量生效
  • 命令行变量
#       命令行变量
$ ./T01.sh  abcd 1234            #以这行命令为例子
#  $0   保存的当前脚本名字(文件名字)
#  $#   代表命令行的参数个数,即2
#  $*   代表所有的参数,即abcd、1234
#  $@   代表所有的参数,即abcd、1234
#  $n   代表第n个参数,如$1表示abcd,$2表示1234
# 两个特殊变量 $?和$$
#  $?   代表最后一个命令的返回值
#  $$   代表当前Shell的进程号PID
#  $!   后台运行的最后一个进程的PID号
#  $-   使用set及其执行时传递给Shell的标志位

特殊符号引号、竖杠(管道)和重定向

  • 引号3种,反引号`` 单引号’’ 双引号””
    • 单引号:单引号内不允许任何变量、元字符、通配符、转义符被shell解析,均被原样输出。

    • 双引号:保护特殊元字符和通配符不被shell解析,但是允许变量和命令的解析,以及转义符的解析。

    • 反引号:反引号的功能是命令替换,在反引号(``) 中的内容通常是命令行,程序会优先执行反引号中 的内容,并使用运行结果替换掉反引号处的内容。

  • 竖杠(管道):前一个命令的输出都作为下一个命令的输入(依次配合完成)
  • 重定向(>、<、>>、<<)
    • Linux的三种设备
      • 标准输入:stdin, 由0表示,默认接收为键盘的输入
      • 标准输出:stdout,由1表示,默认输出为终端窗口
      • 标准错误:stderr, 由2表示,默认输出为终端窗口在这里插入图片描述
$ ls notexist 2> a.txt  #(notexist是一个不存在的文件,所以将错误信息重定向到a.txt中)
$ echo 0< a.txt         #echo读取a.txt的内容
$ echo "hello world" 1>&2  #重定向到标准错误设备
# 在脚本中,在重定向的右边,标准输入、标准设备文件描述符要写成&0、&1和&2

字符串的处理
$ echo "${
     
     #var}"           #计算var变量的字符数
$ echo "${var#apple}"    #删除var变量的左边字符串apple
$ lev=${var%%[a-zA-Z]*}  #删除var变量的右边字符串
#  从右到左 %%贪恋匹配(尽可能多的匹配) %无贪恋原则(尽可能少的匹配)
#  从左到右 ##贪恋匹配                   #无贪恋原则

二、测试语句

  • test语句和方括号[ ]完全等价
    在这里插入图片描述
  • 参数置换:“参数可以是位置参数,也可以是另一个变量”
语法 功能
变量=${参数:-word} 如果设置了参数,则用参数的值置换变量的值,否则用word置换
变量=${参数:=word} 如果设置了参数,则用参数的值置换变量的值,否则word赋给参数,然后word替换给变量
变量=${参数:?word} 如果设置了参数,则用参数的值置换变量的值,否则就显示word并Shell退出
变量=${参数:+word} 如果设置了参数,则用参数的值置换变量的值,否则不进行置换
  • 算术运算 格式: $ [表达式]
    • 表达式是整数、变量和运算符组成的有意义的式子。
    • bash的三种逻辑运算符 !、&&和||;其优先级为! > && > ||
    • bash允许使用圆括号是表达式成为整体,圆括号的优先级最高。

三、语法单元

1、分支控制

  • 单分支语句
# 单分支语句
if [ -e file ] && [ -r file ] then  #file文件是否存在,是否可读
	cat file  #查看该文件
fi
  • if-else的多分支写法
## if-else的多分支写法
if [ -e file ] && [ -r file ] then #方括号内的左右两边都要空格隔开
	cat file
elif [ -e file ] then
	chmod u+r file   #授予读权限
	cat file
else           #只有else不需要then,其他的if-else的分支都需要then
	touch file
fi
  • case分支的写法
## case分支的写法
read VAR             #从键盘接收一个用户输入,付给变量VAR
case $VAR in         #判断VAR变量的值
	1) echo "one";;  #若值为1,则输出one
	2) echo "two";;  #每个分支都必须以双分号作为结束(最后一个分支除外)
	*) echo "unknown"  #星号*匹配任意字符
esac   #必须以esac结尾,1可以是'1'

2、循环控制(三种)

  • while的循环
##while的循环
declare -i n=0      #declare -i 表示该变量为数值
while [ $n -le 100 ] #条件n小于等于100循环
do                   #循环提用do和done包含起来
	echo "$n"
	n=$n+1           #变量n的自加1
done 
  • until的循环
##until的循环
declare -i n=0      #declare -i 表示该变量为数值
until [ $n -gt 100 ] #条件n小于等于100循环 until是条件不成立执行循环体
do                   #循环提用do和done包含起来
	echo "$n"
	n=$n+1           #变量n的自加1
done 
  • for的循环
##for的循环
files=`ls`     #当前目录下的文件名放在变量files中 每个值以空格分开
for i in $files   #遍历files
do
	if [ -f $i ] then   #若是普通文件
		wc -l $i        #计算$i 该文件的行数
	fi
done 

#或者for的另一种写法
##for的循环
for((i=1;i<=10;i++))   #双括号的for循环
do
	sum=$(expr $sum + $i) #expr支持算术运算
	echo $sum             #求和输出sum
done 

3、函数(判断用户是否在线)

##定义函数和函数调用
check_user()  #定义函数 ()中无空格
{
    
    
	if [ $1 = "quit" ] then #若位置参数第一个为quit,则立即退出
		exit                # $0表示文件名,位置参数0,exit表示退出命令
	fi
	
	USER=`who | grep $1 | wc -l`
	if [ $USER -eq 0 ] then
		return 0    #return 该函数结束
	else
		return 1    #用户在先返回1,不在线返回0
	fi
}

while true #死循环
do
	echo -n "input a user name:"   # echo -n 表示不换行
	read USER                      #接收键盘输入
	#上面的的等效写法
	# read -p "input a user name:" USER
	
	check_user $USER      #函数调用 并传递参数$USER
	
	if [ $? -eq 1 ] then  # $?是上一步命令执行的结果接收变量;这里值函数调用后传来的参数值
		echo "[$USER] online."
	else
		echo "[$USER] offline."   
	fi
	
done 

4、trap的命令

  • trap的使用
####     trap的使用

$ trap "" INT                     #当脚本收到信号SIGINT时,忽略该信号
$ trap do_something INT QUIT HUP   #当脚本收到信号INT、QUIT或HUP时执行函数do_something 
$ trap on_exit  EXIT             #当脚本正常退出时,执行on_exit函数

#当脚本正常退出时执行函数on_exit,当脚本文件收到某个信号INT或HUP时执行空指令
#此时冒号代表一个空指令,如果没有冒号,脚本将完全忽略该信号,不做响应,不能立即退出
#执行顺序时由下而上,即先执行冒号空语句,再执行EXIT的执行函数on_exit函数
$ trap on_exit  EXIT
$ trap ":"  INT HUP
  • trap的经典使用
$ trap -l    #产看系统默认支持的信号类型前缀SIG可以忽略

猜你喜欢

转载自blog.csdn.net/weixin_44763594/article/details/125903950