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
done
View 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

 

相关文章

Centos系统之Shell编程基础知识
从Export理解Shell环境和变量生存期
linux shell数组变量、类型及规则
Centos编程Shell基本工作原理方案
Centos操作系统编程之Shell 问答录
rsync-linux备份脚本