22.第六章 Shell脚本编程基础入门(五)

3.bash的配置文件

bash shell的配置文件很多,可以分成下面类别

3.1 按生效范围划分两类

全局配置:针对所有用户

/etc/profile
/etc/profile.d/*.sh
/etc/bashrc

个人配置:只针对特定用户有效

~/.bash_profile
~/.bashrc

3.2 shell登录两种方式分类

3.2.1 交互式登录

  • 直接通过终端输入账号密码登录

  • 使用su - UserName 切换的用户

配置文件执行顺序:

/etc/profile.d/*.sh
/etc/bashrc
/etc/profile
/etc/bashrc #此文件执行两次
~/.bashrc
~/.bash_profile

注意:文件之间的调用关系,写在同一个文件的不同位置,将影响文件的执行顺序

范例:

[root@rocky8 ~]# vim .bashrc
umask 111

[root@rocky8 ~]# vim .bash_profile
umask 333

[root@rocky8 ~]# exit
logout
[root@rocky8 ~]# umask
0333
#后执行的把先执行的给覆盖了

3.2.2 非交互式登录

  • su UserName
  • 图形界面下打开的终端
  • 执行脚本
  • 任何其它的bash实例

执行顺序:

/etc/profile.d/*.sh
/etc/bashrc
.bashrc

3.3 按功能划分分类

profile类和bashrc类

3.3.1 Profile类

profile类为交互式登录的shell提供配置

全局:/etc/profile, /etc/profile.d/*.sh
个人:~/.bash_profile

主要功用:

(1) 用于定义环境变量

(2) 运行命令或脚本

3.3.2 Bashrc类

bashrc类:为非交互式和交互式登录的shell提供配置

全局:/etc/bashrc
个人:~/.bashrc

主要功用:

(1) 定义命令别名和函数

(2) 定义本地变量

3.4 编辑配置文件生效

修改profile和bashrc文件后需生效两种方法:

  1. 重新启动 shell进程
  2. source|. 配置文件

范例:

. ~/.bashrc

3.5 Bash 退出任务

保存在~/.bash_logout文件中(用户),在退出登录shell时运行

功能:

  • 创建自动备份
  • 清除临时文件

范例:

[root@rocky8 ~]# cp /etc/issue /data
[root@rocky8 ~]# ls /data
app.conf  issue  systeminfo.sh  test.sh  test.txt

[root@rocky8 ~]#  vim .bash_logout 
rm -rf /data/*

[root@rocky8 ~]# exit
logout
[root@rocky8 ~]# ls /data
#.bash_logout 这个是退出时执行操作

3.6 练习

1、让所有用户的PATH环境变量的值多出一个路径,例如:/usr/local/apache/bin
2、用户 root 登录时,将命令指示符变成红色,并自动启用如下别名: rm=‘rm -i’
cdnet=‘cd /etc/sysconfig/network-scripts/’
editnet=‘vim /etc/sysconfig/network-scripts/ifcfg-eth0’
editnet=‘vim /etc/sysconfig/network-scripts/ifcfg-eno16777736 或 ifcfg-ens33 ’ (如果系统是CentOS7)
3、任意用户登录系统时,显示红色字体的警示提醒信息“Hi,dangerous!”
4、编写生成脚本基本格式的脚本,包括作者,联系方式,版本,时间,描述等

4.流程控制

4.1 条件选择

4.1.1 条件判断分绍

4.1.1.1 单分支条件

22.第六章 Shell脚本编程基础入门(五)

4.1.1.2 多分支条件

22.第六章 Shell脚本编程基础入门(五)

4.1.2 选择执行 if 语句

格式:

if COMMANDS; then COMMANDS; [ elif COMMANDS; then COMMANDS; ]... [ else COMMANDS; ] fi

单分支

if 判断条件;then
    条件为真的分支代码
    ......
fi

双分支

if 判断条件; then
    条件为真的分支代码1
    ......
else
    条件为假的分支代码2
    ......
fi

多分支

if 判断条件1; then
    条件1为真的分支代码1
    ......
elif 判断条件2; then
    条件2为真的分支代码2
    ......
elif 判断条件3; then
    条件3为真的分支代码3
    ......
...
else
    以上条件都为假的分支代码N
    ......
fi

说明:

  • 多个条件时,逐个条件进行判断,第一次遇为“真”条件时,执行其分支,而后结束整个if语句
  • if 语句可嵌套

范例:

[root@rocky8 bin]# type if
if is a shell keyword
[root@rocky8 bin]# help if
if: if COMMANDS; then COMMANDS; [ elif COMMANDS; then COMMANDS; ]... [ else COMMANDS; ] fi
    Execute commands based on conditional.
    
    The `if COMMANDS' list is executed.  If its exit status is zero, then the
    `then COMMANDS' list is executed.  Otherwise, each `elif COMMANDS' list is
    executed in turn, and if its exit status is zero, the corresponding
    `then COMMANDS' list is executed and the if command completes.  Otherwise,
    the `else COMMANDS' list is executed, if present.  The exit status of the
    entire construct is the exit status of the last command executed, or zero
    if no condition tested true.
    
    Exit Status:
    Returns the status of the last command executed.

范例:

[root@centos6 ~]# declare -f
__udisks () 
{ 
    local IFS='
';
    local cur="${COMP_WORDS[COMP_CWORD]}";
    if [ "${COMP_WORDS[$(($COMP_CWORD - 1))]}" = "--show-info" ]; then
        COMPREPLY=($(compgen -W "$(udisks --enumerate-device-files)" -- $cur));
    else
        if [ "${COMP_WORDS[$(($COMP_CWORD - 1))]}" = "--inhibit-polling" ]; then
            COMPREPLY=($(compgen -W "$(udisks --enumerate-device-files)" -- $cur));
        else
            if [ "${COMP_WORDS[$(($COMP_CWORD - 1))]}" = "--mount" ]; then
                COMPREPLY=($(compgen -W "$(udisks --enumerate-device-files)" -- $cur));
            else
                if [ "${COMP_WORDS[$(($COMP_CWORD - 1))]}" = "--unmount" ]; then
                    COMPREPLY=($(compgen -W "$(udisks --enumerate-device-files)" -- $cur));
                else
                    if [ "${COMP_WORDS[$(($COMP_CWORD - 1))]}" = "--detach" ]; then
                        COMPREPLY=($(compgen -W "$(udisks --enumerate-device-files)" -- $cur));
                    else
                        if [ "${COMP_WORDS[$(($COMP_CWORD - 1))]}" = "--ata-smart-refresh" ]; then
                            COMPREPLY=($(compgen -W "$(udisks --enumerate-device-files)" -- $cur));
                        else
                            if [ "${COMP_WORDS[$(($COMP_CWORD - 1))]}" = "--ata-smart-simulate" ]; then
                                _filedir || return 0;
                            else
                                if [ "${COMP_WORDS[$(($COMP_CWORD - 1))]}" = "--set-spindown" ]; then
                                    COMPREPLY=($(compgen -W "$(udisks --enumerate-device-files)" -- $cur));
                                else
                                    if [ "${COMP_WORDS[$(($COMP_CWORD - 1))]}" = "--poll-for-media" ]; then
                                        COMPREPLY=($(compgen -W "$(udisks --enumerate-device-files)" -- $cur));
                                    else
                                        COMPREPLY=($(IFS=: compgen -W "--dump:--inhibit-polling:--inhibit-all-polling:--enumerate:--enumerate-device-files:--monitor:--monitor-detail:--show-info:--help:--mount:--mount-fstype:--mount-options:--unmount:--unmount-options:--detach:--detach-options:--ata-smart-refresh:--ata-smart-wakeup:--ata-smart-simulate:--set-spindown:--set-spindown-all:--spindown-timeout:--poll-for-media" -- $cur));
                                    fi;
                                fi;
                            fi;
                        fi;
                    fi;
                fi;
            fi;
        fi;
    fi
}

范例:

#根据命令的退出状态来执行命令
[root@rocky8 bin]# vim if_scanip.sh
#!/bin/bash
#
#**********************************************************************************************
#Author:        Raymond
#QQ:            88563128
#Date:          2021-10-10
#FileName:      if_scanip.sh
#URL:           raymond.blog.csdn.net
#Description:   The test script
#Copyright (C): 2021 All rights reserved
#*********************************************************************************************
HOST=172.31.0.7
if ping -c1 -w1 $HOST >& /dev/null;then
    echo "$HOST is UP"
elif grep -q "$HOST" ~/maintenance.txt;then
    echo "$HOST is undergoing maintenance"
else 
    echo "$HOST is unexpextedlu DOWN!"
    exit 1                                                                                                   
fi

[root@rocky8 bin]# bash if_scanip.sh 
172.31.0.7 is UP

范例:身体质量指数 (BMI)

[root@rocky8 bin]# vim if_bmi.sh
#!/bin/bash
#
#**********************************************************************************************
#Author:        Raymond
#QQ:            88563128
#Date:          2021-10-10
#FileName:      if_bmi.sh
#URL:           raymond.blog.csdn.net
#Description:   The test script
#Copyright (C): 2021 All rights reserved
#*********************************************************************************************
read -p "请输入身高(m为单位):" HIGH
if [[ ! "$HIGH" =~ ^[0-2](\.[0-9]{,2})?$ ]];then
    echo "输入错误身高"
    exit 1
fi

read -p "请输入体重(kg为单位):" WEIGHT
if [[ ! "$WEIGHT" =~ ^[0-9]{1,3}$ ]];then
    echo "输入错误身高"
    exit 1
fi

BMI=`echo $WEIGHT/$HIGH^2| bc`
if [ $BMI -le 18 ];then
    echo "太瘦了,多吃点"
elif [ $BMI -lt 24 ];then
    echo "身材很棒!"
else
    echo "太胖了,注意节食,加强运动"
fi

[root@rocky8 bin]# bash if_bmi.sh
请输入身高(m为单位):170
输入错误身高
[root@rocky8 bin]# bash if_bmi.sh
请输入身高(m为单位):1.7
请输入体重(kg为单位):65
身材很棒!

4.1.3 条件判断 case 语句

格式:

case WORD in [PATTERN [| PATTERN]...) COMMANDS ;;]... esac
case 变量引用 in
PAT1)
    分支1
    ;;
PAT2)
    分支2
    ;;
PAT3)
    分支3
    ;;
...
*)
    默认分支
    ;;
esac

case支持glob风格的通配符:

* 任意长度任意字符
? 任意单个字符
[] 指定范围内的任意单个字符
| 或者,如: a|b

范例:

[root@rocky8 bin]# type case
case is a shell keyword
[root@rocky8 bin]# help case
case: case WORD in [PATTERN [| PATTERN]...) COMMANDS ;;]... esac
    Execute commands based on pattern matching.
    
    Selectively execute COMMANDS based upon WORD matching PATTERN.  The
    `|' is used to separate multiple patterns.
    
    Exit Status:
    Returns the status of the last command executed.

范例:

[root@rocky8 bin]# vim case_yesorno.sh
#!/bin/bash
#
#**********************************************************************************************
#Author:        Raymond
#QQ:            88563128
#Date:          2021-10-10
#FileName:      case_yesorno.sh
#URL:           raymond.blog.csdn.net
#Description:   The test script
#Copyright (C): 2021 All rights reserved
#*********************************************************************************************
read -p "Do you agree(yes/no)?" INPUT
INPUT=`echo $INPUT | tr 'A-Z' 'a-z'`
case $INPUT in
y|yes)
    echo "You input is YES"
    ;;
n|no)
    echo "You input is NO"
    ;;
*)
    echo "Input fales,please input yes or no!"
esac

[root@rocky8 bin]# vim case_yesorno2.sh
#!/bin/bash
#
#**********************************************************************************************
#Author:        Raymond
#QQ:            88563128
#Date:          2021-10-10
#FileName:      case_yesorno2.sh
#URL:           raymond.blog.csdn.net
#Description:   The test script
#Copyright (C): 2021 All rights reserved
#*********************************************************************************************
read -p "Do you agree(yes/no)? " INPUT
case $INPUT in
[yY]|[Yy][Ee][Ss])
    echo "You input is YES"
    ;;
[Nn]|[Nn][Oo])
    echo "You input is NO"
    ;;
*)
    echo "Input fales,please input yes or no!"
esac

范例:运维菜单实现版本2

[root@rocky8 bin]# vim work_menu2.sh
#!/bin/bash
#
#**********************************************************************************************
#Author:        Raymond
#QQ:            88563128
#Date:          2021-10-10
#FileName:      work_menu2.sh
#URL:           raymond.blog.csdn.net
#Description:   The test script
#Copyright (C): 2021 All rights reserved
#*********************************************************************************************
. /etc/init.d/functions
echo -e "\E["$[RANDOM%7+31]";1m"
cat <<EOF
请选择:
1)备份数据库
2)清理日志
3)软件升级
4)软件回滚
5)删库跑路
EOF
echo -e "\E[0m"

read -p "请选择上面项对应的数字1-5:" MENU
case $MENU in
1)
    action "备份数据库"
    ;;
2)
    action "清理日志"
    ;;
3)
    action "软件升级"
    ;;
4)
    action "软件回滚"
    ;;
5)
    action "删库跑路"
    ;;
*)
    action "INPUT FALSE!"
esac

4.1.4 练习

1、编写脚本 createuser.sh,实现如下功能:使用一个用户名做为参数,如果指定参数的用户存在,就显示其存在,否则添加之。并设置初始密码为123456,显示添加的用户的id号等信息,在此新用户第一次登录时,会提示用户立即改密码,如果没有参数,就提示:请输入用户名
2、编写脚本 yesorno.sh,提示用户输入yes或no,并判断用户输入的是yes还是no,或是其它信息
3、编写脚本 filetype.sh,判断用户输入文件路径,显示其文件类型(普通,目录,链接,其它文件类型)
4、编写脚本 checkint.sh,判断用户输入的参数是否为正整数
5、编写脚本 reset.sh,实现系统安装后的初始化环境,包括:1、别名 2、环境变量,如PS1等 3、安装常用软件包,如:tree 5、实现固定的IP的设置,6、vim的设置等

4.2 循环

4.2.1 循环执行介绍

22.第六章 Shell脚本编程基础入门(五)

将某代码段重复运行多次,通常有进入循环的条件和退出循环的条件

重复运行次数

  • 循环次数事先已知
  • 循环次数事先未知

常见的循环的命令:for, while, until
22.第六章 Shell脚本编程基础入门(五)

4.2.2 for 循环

[root@rocky8 bin]# type for
for is a shell keyword
[root@rocky8 bin]# help for
for: for NAME [in WORDS ... ] ; do COMMANDS; done
    Execute commands for each member in a list.
    
    The `for' loop executes a sequence of commands for each member in a
    list of items.  If `in WORDS ...;' is not present, then `in "$@"' is
    assumed.  For each element in WORDS, NAME is set to that element, and
    the COMMANDS are executed.
    
    Exit Status:
    Returns the status of the last command executed.

[root@centos7 ~]# help for
for: for NAME [in WORDS ... ] ; do COMMANDS; done
    Execute commands for each member in a list.
    
    The `for' loop executes a sequence of commands for each member in a
    list of items.  If `in WORDS ...;' is not present, then `in "$@"' is
    assumed.  For each element in WORDS, NAME is set to that element, and
    the COMMANDS are executed.
    
    Exit Status:
    Returns the status of the last command executed.
for ((: for (( exp1; exp2; exp3 )); do COMMANDS; done
    Arithmetic for loop.
    
    Equivalent to
    	(( EXP1 ))
    	while (( EXP2 )); do
    		COMMANDS
    		(( EXP3 ))
    	done
    EXP1, EXP2, and EXP3 are arithmetic expressions.  If any expression is
    omitted, it behaves as if it evaluates to 1.
    
    Exit Status:
    Returns the status of the last command executed.

范例:

[root@rocky8 bin]# for i in a b c d;do echo $i;done
a
b
c
d

[root@rocky8 bin]# for i in {a..z};do echo i=$i;done
i=a
i=b
i=c
i=d
i=e
i=f
i=g
i=h
i=i
i=j
i=k
i=l
i=m
i=n
i=o
i=p
i=q
i=r
i=s
i=t
i=u
i=v
i=w
i=x
i=y
i=z

[root@rocky8 bin]# for i in {1..10};do echo i=$i;done
i=1
i=2
i=3
i=4
i=5
i=6
i=7
i=8
i=9
i=10

[root@rocky8 bin]# for i in `seq 10`;do echo i=$i;done
i=1
i=2
i=3
i=4
i=5
i=6
i=7
i=8
i=9
i=10

[root@rocky8 bin]# for file in /etc/*.conf;do echo file=$file;done
file=/etc/dracut.conf
file=/etc/fuse.conf
file=/etc/host.conf
file=/etc/idmapd.conf
file=/etc/kdump.conf
file=/etc/krb5.conf
file=/etc/ld.so.conf
file=/etc/libaudit.conf
file=/etc/libuser.conf
file=/etc/locale.conf
file=/etc/logrotate.conf
file=/etc/man_db.conf
file=/etc/mke2fs.conf
file=/etc/nsswitch.conf
file=/etc/resolv.conf
file=/etc/rsyslog.conf
file=/etc/sestatus.conf
file=/etc/sudo.conf
file=/etc/sudo-ldap.conf
file=/etc/sysctl.conf
file=/etc/tcsd.conf
file=/etc/vconsole.conf
file=/etc/xattr.conf
file=/etc/yum.conf

格式1:

for NAME [in WORDS ... ] ; do COMMANDS; done

for 变量名 [ in 列表 ];do
    循环体
done

for 变量名 [ in 列表 ]
do
    循环体
done

执行机制:

  • 依次将列表中的元素赋值给“变量名”; 每次赋值后即执行一次循环体; 直到列表中的元素耗尽,循环结束
  • 如果省略 [in WORDS … ] ,此时使用位置参数变量 in “$@”

for循环列表生成方式:

  • 直接给出列表
  • 整数列表:
{start..end}
$(seq [start [step]] end)
  • 返回列表的命令:
$(COMMAND)
  • 使用glob,如:*.sh
  • 变量引用,如: @ , @, @,*,$#

范例:面试题,计算1+2+3+…+100的结果

[root@rocky8 bin]# sum=0;for i in {1..100};do let sum+=i;done ;echo sum=$sum
sum=5050

范例:

[root@rocky8 bin]# vim for_sum.sh
#!/bin/bash
#
#**********************************************************************************************
#Author:        Raymond
#QQ:            88563128
#Date:          2021-10-10
#FileName:      for_sum.sh
#URL:           raymond.blog.csdn.net
#Description:   The test script
#Copyright (C): 2021 All rights reserved
#*********************************************************************************************
sum=0
for i in {1..100};do
    let sum+=i
done
echo sum=$sum

[root@rocky8 bin]# bash for_sum.sh 
sum=5050

范例: 九九乘法表

[root@rocky8 bin]# vim for_99.sh
#!/bin/bash
#
#**********************************************************************************************
#Author:        Raymond
#QQ:            88563128
#Date:          2021-10-10
#FileName:      for_99.sh
#URL:           raymond.blog.csdn.net
#Description:   The test script
#Copyright (C): 2021 All rights reserved
#*********************************************************************************************
for i in {1..9};do
    echo $i
done

[root@rocky8 bin]# bash for_99.sh 
1
2
3
4
5
6
7
8
9

[root@rocky8 bin]# vim for_99.sh
#!/bin/bash
#
#**********************************************************************************************
#Author:        Raymond
#QQ:            88563128
#Date:          2021-10-10
#FileName:      for_99.sh
#URL:           raymond.blog.csdn.net
#Description:   The test script
#Copyright (C): 2021 All rights reserved
#*********************************************************************************************
for i in {1..9};do
    for j in `seq $i`;do
        echo $j
    done
done

[root@rocky8 bin]# bash for_99.sh 
1
1
2
1
2
3
1
2
3
4
1
2
3
4
5
1
2
3
4
5
6
1
2
3
4
5
6
7
1
2
3
4
5
6
7
8
1
2
3
4
5
6
7
8
9

[root@rocky8 bin]# vim for_99.sh
#!/bin/bash
#
#**********************************************************************************************
#Author:        Raymond
#QQ:            88563128
#Date:          2021-10-10
#FileName:      for_99.sh
#URL:           raymond.blog.csdn.net
#Description:   The test script
#Copyright (C): 2021 All rights reserved
#*********************************************************************************************
for i in {1..9};do
    for j in `seq $i`;do
        echo -e "$j\c"
    done
    echo
done

[root@rocky8 bin]# bash for_99.sh 
1
12
123
1234
12345
123456
1234567
12345678
123456789

[root@rocky8 bin]# vim for_99.sh
#!/bin/bash
#
#**********************************************************************************************
#Author:        Raymond
#QQ:            88563128
#Date:          2021-10-10
#FileName:      for_99.sh
#URL:           raymond.blog.csdn.net
#Description:   The test script
#Copyright (C): 2021 All rights reserved
#*********************************************************************************************
for i in {1..9};do
    for j in `seq $i`;do
        echo -e "${j}x${i}=$[j*i]\c"
    done
    echo
done

[root@rocky8 bin]# bash for_99.sh 
1x1=1
1x2=22x2=4
1x3=32x3=63x3=9
1x4=42x4=83x4=124x4=16
1x5=52x5=103x5=154x5=205x5=25
1x6=62x6=123x6=184x6=245x6=306x6=36
1x7=72x7=143x7=214x7=285x7=356x7=427x7=49
1x8=82x8=163x8=244x8=325x8=406x8=487x8=568x8=64
1x9=92x9=183x9=274x9=365x9=456x9=547x9=638x9=729x9=81

[root@rocky8 bin]# vim for_99.sh
#!/bin/bash
#
#**********************************************************************************************
#Author:        Raymond
#QQ:            88563128
#Date:          2021-10-10
#FileName:      for_99.sh
#URL:           raymond.blog.csdn.net
#Description:   The test script
#Copyright (C): 2021 All rights reserved
#*********************************************************************************************
for i in {1..9};do
    for j in `seq $i`;do
        echo -e "${j}x${i}=$[i*j]\t\c"
    done
    echo
done

[root@rocky8 bin]# bash for_99.sh 
1x1=1	
1x2=2	2x2=4	
1x3=3	2x3=6	3x3=9	
1x4=4	2x4=8	3x4=12	4x4=16	
1x5=5	2x5=10	3x5=15	4x5=20	5x5=25	
1x6=6	2x6=12	3x6=18	4x6=24	5x6=30	6x6=36	
1x7=7	2x7=14	3x7=21	4x7=28	5x7=35	6x7=42	7x7=49	
1x8=8	2x8=16	3x8=24	4x8=32	5x8=40	6x8=48	7x8=56	8x8=64	
1x9=9	2x9=18	3x9=27	4x9=36	5x9=45	6x9=54	7x9=63	8x9=72	9x9=81

生产案例:将指定目录下的所有文件的后缀改名为 bak 后缀

[root@rocky8 bin]# mkdir /data/test
[root@rocky8 bin]# cd /data/test
[root@rocky8 test]# vim ~/for_rename.sh 
#!/bin/bash
#
#**********************************************************************************************
#Author:        Raymond
#QQ:            88563128
#Date:          2021-10-10
#FileName:      for_rename.sh
#URL:           raymond.blog.csdn.net
#Description:   The test script
#Copyright (C): 2021 All rights reserved
#*********************************************************************************************
DIR=/data/test
cd $DIR
for FILE in * ;do
    PRE=`echo $FILE | sed -nr 's/(.*)\.([^.]+)$/\1/p'`
    #SUFFIX=`echo $FILE | sed -nr 's/(.*)\.([^.]+)$/\2/p'`
    mv $FILE $PRE.bak
done

[root@rocky8 test]# touch {a..c}.txt
[root@rocky8 test]# bash ~/for_rename.sh 
[root@rocky8 test]# ls
a.bak  b.bak  c.bak

范例:面试题,要求将目录YYYY-MM-DD/中所有文件,移动到YYYY-MM/DD/下

#1 yyyy-mm-dd10.sh 创建YYYY-MM-DD,当前日期一年前365天到目前共365个目录,里面有10个文件,$RANDOM.log

[root@rocky8 bin]# vim for_dir.sh
#!/bin/bash
#
#**********************************************************************************************
#Author:        Raymond
#QQ:            88563128
#Date:          2021-10-10
#FileName:      for_dir.sh
#URL:           raymond.blog.csdn.net
#Description:   The test script
#Copyright (C): 2021 All rights reserved
#*********************************************************************************************
PDIR=/data/test
for i in {1..365};do
    SUBDIR=`date -d "-$i day" +%F`
    mkdir $PDIR/$SUBDIR
    cd $PDIR/$SUBDIR 
    for j in {1..10};do
        touch $RANDOM.log
    done
done

[root@rocky8 bin]# bash for_dir.sh 
[root@rocky8 bin]# ls /data/test
2020-10-10  2020-11-10  2020-12-11  2021-01-11  2021-02-11  2021-03-14  2021-04-14  2021-05-15  2021-06-15  2021-07-16  2021-08-16  2021-09-16
2020-10-11  2020-11-11  2020-12-12  2021-01-12  2021-02-12  2021-03-15  2021-04-15  2021-05-16  2021-06-16  2021-07-17  2021-08-17  2021-09-17
2020-10-12  2020-11-12  2020-12-13  2021-01-13  2021-02-13  2021-03-16  2021-04-16  2021-05-17  2021-06-17  2021-07-18  2021-08-18  2021-09-18
2020-10-13  2020-11-13  2020-12-14  2021-01-14  2021-02-14  2021-03-17  2021-04-17  2021-05-18  2021-06-18  2021-07-19  2021-08-19  2021-09-19
2020-10-14  2020-11-14  2020-12-15  2021-01-15  2021-02-15  2021-03-18  2021-04-18  2021-05-19  2021-06-19  2021-07-20  2021-08-20  2021-09-20
2020-10-15  2020-11-15  2020-12-16  2021-01-16  2021-02-16  2021-03-19  2021-04-19  2021-05-20  2021-06-20  2021-07-21  2021-08-21  2021-09-21
2020-10-16  2020-11-16  2020-12-17  2021-01-17  2021-02-17  2021-03-20  2021-04-20  2021-05-21  2021-06-21  2021-07-22  2021-08-22  2021-09-22
2020-10-17  2020-11-17  2020-12-18  2021-01-18  2021-02-18  2021-03-21  2021-04-21  2021-05-22  2021-06-22  2021-07-23  2021-08-23  2021-09-23
2020-10-18  2020-11-18  2020-12-19  2021-01-19  2021-02-19  2021-03-22  2021-04-22  2021-05-23  2021-06-23  2021-07-24  2021-08-24  2021-09-24
2020-10-19  2020-11-19  2020-12-20  2021-01-20  2021-02-20  2021-03-23  2021-04-23  2021-05-24  2021-06-24  2021-07-25  2021-08-25  2021-09-25
2020-10-20  2020-11-20  2020-12-21  2021-01-21  2021-02-21  2021-03-24  2021-04-24  2021-05-25  2021-06-25  2021-07-26  2021-08-26  2021-09-26
2020-10-21  2020-11-21  2020-12-22  2021-01-22  2021-02-22  2021-03-25  2021-04-25  2021-05-26  2021-06-26  2021-07-27  2021-08-27  2021-09-27
2020-10-22  2020-11-22  2020-12-23  2021-01-23  2021-02-23  2021-03-26  2021-04-26  2021-05-27  2021-06-27  2021-07-28  2021-08-28  2021-09-28
2020-10-23  2020-11-23  2020-12-24  2021-01-24  2021-02-24  2021-03-27  2021-04-27  2021-05-28  2021-06-28  2021-07-29  2021-08-29  2021-09-29
2020-10-24  2020-11-24  2020-12-25  2021-01-25  2021-02-25  2021-03-28  2021-04-28  2021-05-29  2021-06-29  2021-07-30  2021-08-30  2021-09-30
2020-10-25  2020-11-25  2020-12-26  2021-01-26  2021-02-26  2021-03-29  2021-04-29  2021-05-30  2021-06-30  2021-07-31  2021-08-31  2021-10-01
2020-10-26  2020-11-26  2020-12-27  2021-01-27  2021-02-27  2021-03-30  2021-04-30  2021-05-31  2021-07-01  2021-08-01  2021-09-01  2021-10-02
2020-10-27  2020-11-27  2020-12-28  2021-01-28  2021-02-28  2021-03-31  2021-05-01  2021-06-01  2021-07-02  2021-08-02  2021-09-02  2021-10-03
2020-10-28  2020-11-28  2020-12-29  2021-01-29  2021-03-01  2021-04-01  2021-05-02  2021-06-02  2021-07-03  2021-08-03  2021-09-03  2021-10-04
2020-10-29  2020-11-29  2020-12-30  2021-01-30  2021-03-02  2021-04-02  2021-05-03  2021-06-03  2021-07-04  2021-08-04  2021-09-04  2021-10-05
2020-10-30  2020-11-30  2020-12-31  2021-01-31  2021-03-03  2021-04-03  2021-05-04  2021-06-04  2021-07-05  2021-08-05  2021-09-05  2021-10-06
2020-10-31  2020-12-01  2021-01-01  2021-02-01  2021-03-04  2021-04-04  2021-05-05  2021-06-05  2021-07-06  2021-08-06  2021-09-06  2021-10-07
2020-11-01  2020-12-02  2021-01-02  2021-02-02  2021-03-05  2021-04-05  2021-05-06  2021-06-06  2021-07-07  2021-08-07  2021-09-07  2021-10-08
2020-11-02  2020-12-03  2021-01-03  2021-02-03  2021-03-06  2021-04-06  2021-05-07  2021-06-07  2021-07-08  2021-08-08  2021-09-08  2021-10-09
2020-11-03  2020-12-04  2021-01-04  2021-02-04  2021-03-07  2021-04-07  2021-05-08  2021-06-08  2021-07-09  2021-08-09  2021-09-09
2020-11-04  2020-12-05  2021-01-05  2021-02-05  2021-03-08  2021-04-08  2021-05-09  2021-06-09  2021-07-10  2021-08-10  2021-09-10
2020-11-05  2020-12-06  2021-01-06  2021-02-06  2021-03-09  2021-04-09  2021-05-10  2021-06-10  2021-07-11  2021-08-11  2021-09-11
2020-11-06  2020-12-07  2021-01-07  2021-02-07  2021-03-10  2021-04-10  2021-05-11  2021-06-11  2021-07-12  2021-08-12  2021-09-12
2020-11-07  2020-12-08  2021-01-08  2021-02-08  2021-03-11  2021-04-11  2021-05-12  2021-06-12  2021-07-13  2021-08-13  2021-09-13
2020-11-08  2020-12-09  2021-01-09  2021-02-09  2021-03-12  2021-04-12  2021-05-13  2021-06-13  2021-07-14  2021-08-14  2021-09-14
2020-11-09  2020-12-10  2021-01-10  2021-02-10  2021-03-13  2021-04-13  2021-05-14  2021-06-14  2021-07-15  2021-08-15  2021-09-15

[root@rocky8 bin]# tree /data/test

#2 移动到YYYY-MM/DD下

[root@rocky8 bin]# vim for_mv.sh
#!/bin/bash
#
#**********************************************************************************************
#Author:        Raymond
#QQ:            88563128
#Date:          2021-10-10
#FileName:      for_mv.sh
#URL:           raymond.blog.csdn.net
#Description:   The test script
#Copyright (C): 2021 All rights reserved
#*********************************************************************************************
DIR=/data/test
cd $DIR
for SRC in *;do
    YYYY_MM=`echo $SRC | cut -d"-" -f1,2`
    DD=`echo $SRC | cut -d"-" -f3`
    [ -d ${YYYY_MM}/$DD ] || mkdir -p ${YYYY_MM}/$DD &> /dev/null
    mv $SRC/* ${YYYY_MM}/$DD
done
rm -rf $DIR/*-*-*

[root@rocky8 bin]# bash for_mv.sh 
[root@rocky8 bin]# ls /data/test
2020-10  2020-11  2020-12  2021-01  2021-02  2021-03  2021-04  2021-05  2021-06  2021-07  2021-08  2021-09  2021-10

面试题:扫描一个网段:172.31.0.0/21(172.31.0.1—172.31.0.254),判断此网段中主机在线状态,将在线的主机的IP打印出来

[root@rocky8 bin]# vim for_scan_host.sh
#!/bin/bash
#
#**********************************************************************************************
#Author:        Raymond
#QQ:            88563128
#Date:          2021-10-10
#FileName:      for_scan_host.sh
#URL:           raymond.blog.csdn.net
#Description:   The test script
#Copyright (C): 2021 All rights reserved
#*********************************************************************************************
NET=172.31.0
for ID in {1..254};do
    {
    ping -c1 -w1 $NET.$ID &> /dev/null && echo $NET.$ID is up || echo $NET.$ID is down
    }&
done
wait

[root@rocky8 bin]# bash for_scan_host.sh 
172.31.0.2 is up
172.31.0.7 is up
172.31.0.6 is up
172.31.0.41 is down
172.31.0.45 is down
172.31.0.10 is down
172.31.0.20 is down
172.31.0.14 is down
172.31.0.43 is down
172.31.0.30 is down
172.31.0.17 is down
172.31.0.35 is down
172.31.0.16 is down
172.31.0.22 is down
172.31.0.19 is down
172.31.0.34 is down
172.31.0.40 is down
172.31.0.26 is down
172.31.0.15 is down
172.31.0.36 is down
172.31.0.46 is down
172.31.0.32 is down
172.31.0.49 is down
172.31.0.38 is down
172.31.0.24 is down
172.31.0.44 is down
172.31.0.37 is down
172.31.0.33 is down
172.31.0.11 is down
172.31.0.27 is down
172.31.0.3 is down
172.31.0.4 is down
172.31.0.8 is down
172.31.0.9 is down
172.31.0.13 is down
172.31.0.18 is down
172.31.0.23 is down
172.31.0.28 is down
172.31.0.29 is down
172.31.0.31 is down
172.31.0.39 is down
172.31.0.42 is down
172.31.0.48 is down
172.31.0.5 is down
172.31.0.12 is down
172.31.0.47 is down
172.31.0.1 is down
172.31.0.25 is down
172.31.0.21 is down
172.31.0.50 is down
172.31.0.51 is down
172.31.0.84 is down
172.31.0.66 is down
172.31.0.81 is down
172.31.0.62 is down
172.31.0.78 is down
172.31.0.76 is down
172.31.0.83 is down
172.31.0.72 is down
172.31.0.79 is down
172.31.0.57 is down
172.31.0.69 is down
172.31.0.63 is down
172.31.0.68 is down
172.31.0.52 is down
172.31.0.56 is down
172.31.0.53 is down
172.31.0.54 is down
172.31.0.61 is down
172.31.0.70 is down
172.31.0.71 is down
172.31.0.74 is down
172.31.0.82 is down
172.31.0.65 is down
172.31.0.75 is down
172.31.0.77 is down
172.31.0.64 is down
172.31.0.59 is down
172.31.0.58 is down
172.31.0.60 is down
172.31.0.73 is down
172.31.0.80 is down
172.31.0.55 is down
172.31.0.67 is down
172.31.0.85 is down
172.31.0.86 is down
172.31.0.143 is down
172.31.0.144 is down
172.31.0.150 is down
172.31.0.145 is down
172.31.0.133 is down
172.31.0.149 is down
172.31.0.121 is down
172.31.0.124 is down
172.31.0.131 is down
172.31.0.119 is down
172.31.0.132 is down
172.31.0.102 is down
172.31.0.128 is down
172.31.0.136 is down
172.31.0.116 is down
172.31.0.146 is down
172.31.0.114 is down
172.31.0.137 is down
172.31.0.99 is down
172.31.0.101 is down
172.31.0.111 is down
172.31.0.117 is down
172.31.0.151 is down
172.31.0.90 is down
172.31.0.110 is down
172.31.0.140 is down
172.31.0.87 is down
172.31.0.104 is down
172.31.0.97 is down
172.31.0.118 is down
172.31.0.93 is down
172.31.0.95 is down
172.31.0.103 is down
172.31.0.105 is down
172.31.0.134 is down
172.31.0.107 is down
172.31.0.109 is down
172.31.0.112 is down
172.31.0.130 is down
172.31.0.106 is down
172.31.0.88 is down
172.31.0.89 is down
172.31.0.92 is down
172.31.0.100 is down
172.31.0.123 is down
172.31.0.127 is down
172.31.0.129 is down
172.31.0.141 is down
172.31.0.148 is down
172.31.0.122 is down
172.31.0.94 is down
172.31.0.91 is down
172.31.0.108 is down
172.31.0.115 is down
172.31.0.125 is down
172.31.0.138 is down
172.31.0.139 is down
172.31.0.147 is down
172.31.0.113 is down
172.31.0.96 is down
172.31.0.135 is down
172.31.0.126 is down
172.31.0.98 is down
172.31.0.120 is down
172.31.0.142 is down
172.31.0.201 is down
172.31.0.189 is down
172.31.0.192 is down
172.31.0.199 is down
172.31.0.187 is down
172.31.0.200 is down
172.31.0.169 is down
172.31.0.196 is down
172.31.0.188 is down
172.31.0.184 is down
172.31.0.182 is down
172.31.0.166 is down
172.31.0.152 is down
172.31.0.163 is down
172.31.0.168 is down
172.31.0.179 is down
172.31.0.185 is down
172.31.0.203 is down
172.31.0.157 is down
172.31.0.194 is down
172.31.0.178 is down
172.31.0.180 is down
172.31.0.155 is down
172.31.0.171 is down
172.31.0.164 is down
172.31.0.186 is down
172.31.0.160 is down
172.31.0.162 is down
172.31.0.170 is down
172.31.0.202 is down
172.31.0.175 is down
172.31.0.177 is down
172.31.0.191 is down
172.31.0.209 is down
172.31.0.190 is down
172.31.0.204 is down
172.31.0.161 is down
172.31.0.165 is down
172.31.0.205 is down
172.31.0.208 is down
172.31.0.154 is down
172.31.0.156 is down
172.31.0.159 is down
172.31.0.167 is down
172.31.0.195 is down
172.31.0.197 is down
172.31.0.158 is down
172.31.0.176 is down
172.31.0.183 is down
172.31.0.193 is down
172.31.0.206 is down
172.31.0.207 is down
172.31.0.181 is down
172.31.0.210 is down
172.31.0.153 is down
172.31.0.172 is down
172.31.0.211 is down
172.31.0.212 is down
172.31.0.213 is down
172.31.0.214 is down
172.31.0.173 is down
172.31.0.174 is down
172.31.0.198 is down
172.31.0.215 is down
172.31.0.221 is down
172.31.0.224 is down
172.31.0.217 is down
172.31.0.220 is down
172.31.0.219 is down
172.31.0.222 is down
172.31.0.218 is down
172.31.0.223 is down
172.31.0.216 is down
172.31.0.225 is down
172.31.0.228 is down
172.31.0.230 is down
172.31.0.229 is down
172.31.0.226 is down
172.31.0.232 is down
172.31.0.233 is down
172.31.0.227 is down
172.31.0.231 is down
172.31.0.234 is down
172.31.0.240 is down
172.31.0.235 is down
172.31.0.243 is down
172.31.0.244 is down
172.31.0.236 is down
172.31.0.237 is down
172.31.0.239 is down
172.31.0.242 is down
172.31.0.241 is down
172.31.0.238 is down
172.31.0.251 is down
172.31.0.252 is down
172.31.0.253 is down
172.31.0.245 is down
172.31.0.254 is down
172.31.0.249 is down
172.31.0.250 is down
172.31.0.247 is down
172.31.0.248 is down
172.31.0.246 is down

格式2
双小括号方法,即((…))格式,也可以用于算术运算,双小括号方法也可以使bash Shell实现C语言风格的变量操作
I=10;((I++))
22.第六章 Shell脚本编程基础入门(五)

for ((: for (( exp1; exp2; exp3 )); do COMMANDS; done

for ((控制变量初始化;条件判断表达式;控制变量的修正表达式))
do
    循环体
done

说明:

  • 控制变量初始化:仅在运行到循环代码段时执行一次
  • 控制变量的修正表达式:每轮循环结束会先进行控制变量修正运算,而后再做条件判断

范例:

[root@rocky8 bin]# vim for_sum2.sh
#!/bin/bash
#
#**********************************************************************************************
#Author:        Raymond
#QQ:            88563128
#Date:          2021-10-10
#FileName:      for_sum2.sh
#URL:           raymond.blog.csdn.net
#Description:   The test script
#Copyright (C): 2021 All rights reserved
#*********************************************************************************************
for ((i=1;i<=100;i++));do
    let sum+=i
done
echo sum=$sum

[root@rocky8 bin]# bash for_sum2.sh
sum=5050

[root@rocky8 bin]# vim for_sum.sh 
#!/bin/bash
#
#**********************************************************************************************
#Author:        Raymond
#QQ:            88563128
#Date:          2021-10-10
#FileName:      for_sum.sh
#URL:           raymond.blog.csdn.net
#Description:   The test script
#Copyright (C): 2021 All rights reserved
#*********************************************************************************************
N=100
for ((i=1;i<=$N;i++));do                                                                                      
    let sum+=i
done
echo sum=$sum

[root@rocky8 bin]# bash for_sum.sh
sum=5050

范例:九九乘法表

[root@rocky8 bin]# vim for_99_2.sh
#!/bin/bash
#
#**********************************************************************************************
#Author:        Raymond
#QQ:            88563128
#Date:          2021-10-10
#FileName:      for_99_2.sh
#URL:           raymond.blog.csdn.net
#Description:   The test script
#Copyright (C): 2021 All rights reserved
#*********************************************************************************************
for((i=1;i<10;i++));do
    for((j=1;j<=i;j++));do
        echo -e "${j}x$i=$((j*i))\t\c"
    done
    echo
done

[root@rocky8 bin]# bash for_99_2.sh 
1x1=1	
1x2=2	2x2=4	
1x3=3	2x3=6	3x3=9	
1x4=4	2x4=8	3x4=12	4x4=16	
1x5=5	2x5=10	3x5=15	4x5=20	5x5=25	
1x6=6	2x6=12	3x6=18	4x6=24	5x6=30	6x6=36	
1x7=7	2x7=14	3x7=21	4x7=28	5x7=35	6x7=42	7x7=49	
1x8=8	2x8=16	3x8=24	4x8=32	5x8=40	6x8=48	7x8=56	8x8=64	
1x9=9	2x9=18	3x9=27	4x9=36	5x9=45	6x9=54	7x9=63	8x9=72	9x9=81	

范例:等腰三角形

[root@rocky8 bin]# vim for_triangle.sh
#!/bin/bash
#
#**********************************************************************************************
#Author:        Raymond
#QQ:            88563128
#Date:          2021-10-10
#FileName:      for_triangle.sh
#URL:           raymond.blog.csdn.net
#Description:   The test script
#Copyright (C): 2021 All rights reserved
#*********************************************************************************************
read -p "请输入三角形的行数:" line
for ((i=1;i<=line;i++));do
    for ((k=0;k<=line-i;k++));do
        echo -e ' \c'
    done
    for ((j=1;j<=2*i-1;j++));do
        echo -e '*\c'
    done
    echo
done

[root@rocky8 bin]# bash for_triangle.sh 
请输入三角形的行数:10
          *
         ***
        *****
       *******
      *********
     ***********
    *************
   ***************
  *****************
 *******************

范例:生成进度

[root@rocky8 bin]# for ((i=0;i<=100;i++));do printf "\e[4D%3d%%" $i;sleep 0.1s;done
100%

范例:

[root@rocky8 bin]# for((;;));do echo for;sleep 1;done
for
for
for
for
for
for
for

4.2.3 练习:用 for 实现

1、判断/var/目录下所有文件的类型
2、添加10个用户user1-user10,密码为8位随机字符
3、/etc/rc.d/rc3.d目录下分别有多个以K开头和以S开头的文件;分别读取每个文件,以K开头的输出为文件加stop,以S开头的输出为文件名加start,如K34filename stop S66filename start
4、编写脚本,提示输入正整数n的值,计算1+2+…+n的总和
5、计算100以内所有能被3整除的整数之和
6、编写脚本,提示请输入网络地址,如192.168.0.0,判断输入的网段中主机在线状态
7、打印九九乘法表
8、在/testdir目录下创建10个html文件,文件名格式为数字N(从1到10)加随机8个字母,如:1AbCdeFgH.html
9、打印等腰三角形
10、猴子第一天摘下若干个桃子,当即吃了一半,还不瘾,又多吃了一个。第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。到第10天早上想再吃时,只剩下一个桃子了。求第一天共摘了多少?

上一篇:最初阶的螺旋矩阵(C语言实现)


下一篇:修饰符