shell-进阶1
作者:互联网
[root@centos8 ~]# lscpu Architecture: x86_64 #架构 CPU op-mode(s): 32-bit, 64-bit #指令集 Byte Order: Little Endian CPU(s): 8 #核数 On-line CPU(s) list: 0-7 Thread(s) per core: 1 #每个core 有几个线程 Core(s) per socket: 4 #每个槽位有4个core Socket(s): 2 #服务器面板上有2个cpu 槽位 NUMA node(s): 2 #nodes的数量反引号不能嵌套,$()可以嵌套使用
root@ubuntu2004:~# echo `date +%F`.txt 2022-04-15.txt root@ubuntu2004:~# ll `echo `date +%F`.txt` .txt: command not found ls: cannot access 'date': No such file or directory ls: cannot access '+%F': No such file or directory
root@ubuntu2004:~# echo $(date +%F).txt 2022-04-15.txt root@ubuntu2004:~# ll $(echo $(date +%F).txt) -rw-r--r-- 1 root root 0 Apr 15 12:37 2022-04-15.txt输出信息 echo -n 不自动换行 -E 启用解释功能 -e 启用 \ 字符的解释功能 echo -e '\E[42;38;1;5m川哥\E[0m' 比较 “ ” ,‘ ’, ``三者区别
root@ubuntu2004:~# echo $HOSTNAME ubuntu2004 root@ubuntu2004:~# echo 'echo $HOSTNAME' echo $HOSTNAME root@ubuntu2004:~# echo "echo $HOSTNAME" echo ubuntu2004 root@ubuntu2004:~# echo `echo $HOSTNAME` ubuntu2004
#结论:
单引号:强引用,六亲不认,变量和命令都不识别,都当成了普通的字符串,"最傻" 双引号:弱引用,不能识别命令,可以识别变量,"半傻不精" 反向单引号:里面的内容必须是能执行的命令并且有输出信息,变量和命令都识别,并且会将反向单引号的内容当成命令进行执行后,再交给调用反向单引号的命令继续,"最聪明"括号扩展:{ } root@ubuntu2004:~# echo {1..10} 1 2 3 4 5 6 7 8 9 10变量引用
变量的生效范围等标准划分变量类型 1.普通变量:生效范围为当前shell进程;对当前shell之外的其它shell进程,包括当前shell的子shell 进程均无效 2.环境变量:生效范围为当前shell进程及其子进程 3.本地变量:生效范围为当前shell进程中某代码片断,通常指函数多个变量使用的时候一定用花括号括起来,不然会把下划线也当变量名的一部分
root@ubuntu2004:~# echo ${name}_$age chuange_21
root@ubuntu2004:~# echo $name_$age 21
环境变量
可以使子进程(包括孙子进程)继承父进程的变量,但是无法让父进程使用子进程的变量。 一旦子进程修改从父进程继承的变量,将会新的值传递给孙子进程 一般只在系统配置文件中使用,在脚本中较少使用
root@ubuntu2004:~# export name=chuan root@ubuntu2004:~# declare -x name2=chuange
查看
env printenv export declare -x
位置变量
$1,$2,...对应第1个、第2个等参数,shift [n]换位置 $0 命令本身,包括路径 $* 传递给脚本的所有参数,全部参数合为一个字符串 $@ 传递给脚本的所有参数,每个参数为独立字符串 $# 传递给脚本的参数的个数$*`:表示将变量看成一个整体 `$@`:表示变量是独立的 $$当前所在进程的进程号,如`echo $$
注意: $@ $*只在被双引号包起来的时候才会有差异
循环 while
说明: CONDITION:循环控制条件;进入循环之前,先做一次判断;每一次循环之后会再次做判断;条件为“true”,则执行一次循环;直到条件测试状态为“false”终止循环,因此:CONDTION一般应该有循环 控制变量;而此变量的值会在循环体不断地被修正 进入条件:CONDITION为 true 退出条件:CONDITION为 false 无限循环root@ubuntu2004:~# sum=0;i=1;while ((i<=100));do let sum+=i;let i++;done;echo $sum 5050
root@ubuntu2004:~# sum=0;for i in {1..100};do let sum+=i;done;echo $sum 5050
root@ubuntu2004:~# for ((sum=0,i=1;i<=100;i++));do let sum+=i;done;echo $sum 5050
root@ubuntu2004:/mysql# df |grep '^\/dev\/sd' |tr -s ' ' |cut -d " " -f5 |tr -d "%" |sort -nr|head -1 13
root@ubuntu2004:/mysql# df |sed -En '/^\/dev\/sd/p' /dev/sda2 999320 110432 820076 12% /boot /dev/sdb1 20960256 2685944 18274312 13% /mysql
df |sed -En '/^\/dev\/sd/s#@#\1#p'
root@ubuntu2004:/mysql# df |sed -En '/^\/dev\/sd/s#.* ([0-9]+)%.*#\1#p' 12 ^开头 \说明/无特殊含义 + [0-9]一个或多个 ()分组 第一个分组打印 s# #\1/p 13
-n 不输出模式空间内容到屏幕,即不自动打印 -E 使用扩展正则表达式
-r:使用扩展正则表达式
[root@Rocky8 ~]# cat while_diskcheck.sh #!/bin/bash WARDING=2 while :;do USE=`df |sed -rn '/^\/dev\/sd/s#.* ([0-9]+)%.*#\1#p'` if [ ${USE} -gt ${WARDING} ];then echo "Disk will be full 192.168.80.171" | mail -s "disk warning" 18505420408@qq.com fi sleep 1 done
"-n"可用于测试shell脚本是否存在语法错误,但不会实际执行命令。
"-x"选项使shell在执行脚本的过程中把它实际执行的每一个命令行显示出来
$[]和$(()) 是一组 标识的是 算术运算 +-*/%
[root@Rocky8 script]# echo $(($RANDOM%33+1)) 15
[root@Rocky8 script]# cat 600W双色球.sh #!/bin/bash #FileName :600W.sh RED='\033[31m' BLUE='\033[34m' END='\033[0m' echo -en "$RED 红色:$END" #sleep 3 while true;do red=$[$RANDOM%33+1] echo $redstring | grep -qw $red && continue echo -ne " $RED$red$END" redstring="$redstring $red" sleep 1 [ `echo $redstring | awk "{print NF}"` -eq 6 ] && break done echo echo -ne "$BLUE 篮球:$END \t"; sleep 1 echo -e "$BLUE $[ $RANDOM%16+1 ] $END "
[root@Rocky8 etc]# echo --- 22 --- 33 --- 44| awk '{print NF}'
6
[root@Rocky8 etc]# echo --- 22 --- 33 --- 44| awk '{print $NF}'
44
前者是输出了域个数,后者是输出最后一个字段的内容
grep -q 不打印,静默 -w 精准匹配
[root@Rocky8 script]# bash 600W双色球.sh 红色: 5 26 3 2 10 篮球: 3
[root@Rocky8 script]# cat chess1.sh #!/bin/bash for i in {1..8};do temp1=$[ $i % 2 ] for j in {1..8};do temp2=$[ $j % 2 ] if [ $temp1 -eq $temp2 ];then echo -e -n "\033[47m \033[0m" else echo -e -n "\033[41m \033[0m" fi done echo done [root@Rocky8 script]# cat chess6.sh #!/bin/bash #Author:wang red(){ echo -e "\033[41m \033[0m\c" } yel(){ echo -e "\033[43m \033[0m\c" } redyel(){ for ((i=1;i<=4;i++));do for ((j=1;j<=4;j++));do red;yel done echo done } yelred(){ for ((i=1;i<=4;i++));do for ((j=1;j<=4;j++));do yel;red done echo done } for ((line=1;line<=8;line++));do [ $[$line%2] -eq 0 ] && redyel || yelred doneView Code
&> 标准输出错误输出都丢弃
[root@Rocky8 script]# cat url.sh #!/bin/bash while read url;do curl $url &> /dev/null || echo "$url is failed" done < curl.txt [root@Rocky8 script]# bash url.sh www.chuan.com is failed
[root@Rocky8 script]# cat url.sh #!/bin/bash cat curl.txt | while read url;do curl $url &> /dev/null || echo "$url is failed" done
while read 双变量报警
[root@Rocky8 script]# df |sed -En '/^\/dev\/sd/s#^([^ ]+).* ([0-9]+).*#\1 \2#p' /dev/sda1 26
[root@Rocky8 ~]# cat while_diskcheck2.sh #!/bin/bash WARDING=2 df | sed -En '/^\/dev\/sd/s#^([^ ]+).* ([0-9]+).*#\1 \2#p' | while read DISK USE ;do [ ${USE} -gt ${WARDING} ] && echo "$DISK will be full ,use $USE" | mail -s "disk warning" 814712473@qq.com done
循环 until
while 取反
[root@Rocky8 ~]# sum=0;i=1;until ((i>100));do let sum+=i;let i++;done;echo $sum
5050
[root@Rocky8 ~]# sum=0;i=1;until ! ((i<=100));do let sum+=i;let i++;done;echo $sum 5050
循环控制语句 continue
提前结束第N层的本轮循环,而直接进入下一轮判断[root@Rocky8 ~]# for i in {1..10};do [ $i -eq 5 ] && continue;echo $i;done 1 2 3 4 6 7 8 9 10 [root@Rocky8 ~]# for i in {1..10};do [ $i -eq 5 ] && break;echo $i;done 1 2 3 4
循环控制 shift 命令
shift [n] 用于将参量列表 list 左移指定次数,缺省为左移一次。 参量列表 list 一旦被移动,最左端的那个参数就从列表中删除。while 循环遍历位置参量列表时,常用到 shift[root@Rocky8 script]# bash useradd.sh e f g h e is created g is created [root@Rocky8 script]# cat useradd.sh #!/bin/bash while [ "$1" ];do useradd $1 && echo $1 is created shift 2 done
[root@Rocky8 script]# cat guess.sh #!/bin/bash COLOR='echo -e \E[1;36m' END='\E[0m' read -p "请输入你想猜的数字大小区间(10或10的倍数),此大小区间决定你能猜的次数(q退出游戏):" INPUT_NUM if [ $INPUT_NUM = q ] &> /dev/null;then exit elif [[ $INPUT_NUM =~ ^[1-9]+[0]+$ ]] &> /dev/null;then NUM=$[RANDOM%$INPUT_NUM] var=0 if [ $INPUT_NUM -lt 500 ];then var=6 elif [ $INPUT_NUM -lt 1000 ];then var=8 else var=10 fi $COLOR "本轮你可以猜想$var次" $END while [ $var -ne 0 ] ;do echo read -p "请输入你猜的数字:" TEST_NUM if [ $TEST_NUM -gt $INPUT_NUM ] &> /dev/null;then $COLOR "你输入了错误的数值,你浪费了一次机会!" $END let var-=1 elif [ $TEST_NUM -eq $NUM ] &> /dev/null;then echo -e "\E[1;33m 你猜对了!" $END break elif [ $TEST_NUM -lt $NUM ] &> /dev/null;then $COLOR "数字太小了!" $END let var-=1 elif [ $TEST_NUM -gt $NUM ] &> /dev/null;then $COLOR "数字太大了!" $END let var-=1 elif [ $TEST_NUM = q ] &> /dev/null;then $COLOR "再见~" $END exit else $COLOR "请输入数字!" $END fi [ $var -gt 0 ] && echo -e "你还剩余次数:\E[1;31m$var\E[0m" || echo -e "\E[1;31m你已经失败了!\E[0m" done else $COLOR "请输入正确的区间!" $END ./guess.sh fi
select 菜单
[root@Rocky8 script]# select menu in a b c d e 退出; do echo $menu;[ $REPLY -eq 6 ] && break;done 1) a 2) b 3) c 4) d 5) e 6) 退出 请输入字母编号6 退出
函数调用
[root@Rocky8 script]# cat install_nginx2.sh #!/bin/bash NGINX_VERSION=1.20.2 INSTALL_DIR=/apps/nginx color () { RES_COL=60 MOVE_TO_COL="echo -en \\033[${RES_COL}G" SETCOLOR_SUCCESS="echo -en \\033[1;32m" SETCOLOR_FAILURE="echo -en \\033[1;31m" SETCOLOR_WARNING="echo -en \\033[1;33m" SETCOLOR_NORMAL="echo -en \E[0m" echo -n "$1" && $MOVE_TO_COL echo -n "[" if [ $2 = "success" -o $2 = "0" ] ;then ${SETCOLOR_SUCCESS} echo -n $" OK " elif [ $2 = "failure" -o $2 = "1" ] ;then ${SETCOLOR_FAILURE} echo -n $"FAILED" else ${SETCOLOR_WARNING} echo -n $"WARNING" fi ${SETCOLOR_NORMAL} echo -n "]" echo } install_nginx(){ wget http://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz || { echo "下载失败!";exit 20; } tar xf nginx-${NGINX_VERSION}.tar.gz -C /usr/local/src yum -y install gcc openssl-devel pcre-devel cd /usr/local/src/nginx-${NGINX_VERSION} ./configure --prefix=${INSTALL_DIR} --with-http_ssl_module make -j `grep -c processor /proc/cpuinfo`&& make install if [ $? -ne 0 ];then color "Install nginx is failed!" 1 exit 10 else color "Install nginx is finished!" 0 fi } prepare_html(){ echo "<h1>welcome to 川哥 nginx website </h1>" > ${INSTALL_DIR}/html/index.html } start_nginx(){ /apps/nginx/sbin/nginx } main () { install_nginx prepare_html start_nginx } main
trap 捕捉信号
[root@Rocky8 script]# cat trap.sh #!/bin/bash trap "echo 'Press ctrl+c or ctrl+\ '" int quit #两个信号 trap -p for((i=0;i<=10;i++)) do sleep 1 echo $i done trap '' int #忽略并打印 trap -p for((i=11;i<=20;i++)) do sleep 1 echo $i done trap '-' int #忽略 trap -p for((i=21;i<=30;i++)) do sleep 1 #撤销 echo $i done
退出触发finish函数
[root@Rocky8 script]# cat trap_finish.sh #!/bin/bash finish(){ echo "Finish at `date +%F_%T`" | tee -a /root/finish.log } trap finish exit while true ;do echo running sleep 1 done
创建临时文件,确保唯一
[root@Rocky8 data]# mktemp chuanXXX chuanLqq [root@Rocky8 data]# mktemp -d XXXchuandir Dwrchuandir
标签:shell,ubuntu2004,dev,echo,sh,root,Rocky8,进阶 来源: https://www.cnblogs.com/gxc888/p/16151041.html