[华为云在线课程][Shell脚本编程基础][第三章BashShell配置和流程控制][学习笔记]
bash shell的配置文件
bash shell的配置文件很多,可以分成下面类别
按生效范围划分两类
全局配置:针对所有用户皆有效
/etc/profile
/etc/profile.d/*.sh
/etc/bashrc
个人配置:只针对特定用户有效
~/.bash_profile
~/.bashrc
shell登录两种方式分类
交互式登录
1,直接通过终端输入账号密码登录
2,使用su - username
切换用户
配置文件生效和执行顺序
#放在每个文件最前面
/etc/profile
/etc/profile.d/*.sh
/etc/bashrc
~/.bash_profile
~/.bashrc
/etc/bashrc
#放在每个文件最后
/etc/profile.d/*.sh
/etc/bashrc
/etc/profile
/etc/bashrc #此文件执行两次
注意:文件之间的调用关系,写在同一个文件的不同位置,将影响文件的执行顺序
非交互式登录
1,su username
2,图形界面下打开的终端
3,执行脚本
4,任何其他的bash示例
执行顺序:
/etc/profile.d/*.sh
/etc/bashrc
~/.bashrc
例子:将命令放在最前面
/etc/profile
/etc/profile.d/test.sh
/etc/bashrc
~/.bash_profile
~/.bashrc
/etc/bashrc
su - root
/etc/profile
/etc/profile.d/test.sh
/etc/bashrc
~/.bash_profile
~/.bashrc
/etc/bashrc
exit
su root
~/.bashrc
/etc/bashrc
/etc/profile.d/test.sh
按功能划分分类
Profile类
profile类为交互式登录的shell提供配置
全局:/etc/profile,/etc/profile.d/*.sh
个人:~/.bash_profile
Bashec类
bashrc类:为非交互式和交互式登录的shell提供配置
全局:/etc/bashrc
个人:~/.bashrc
功能:
1,定义命令别名和函数
2,定义本地变量
编辑配置文件生效
修改profile和bashrc文件后需生效的两种方法:
1,重新启动shell进程
2,source|. 配置文件
注意:source会在当前shell中执行脚本,所有一般只用于执行配置文件,或在脚本中调用另一个脚本的场景
例子:
. ~/.bashrc
bash退出任务
保存在~/.bash_logout文件中(用户),在退出登录shell时运行
功能:创建自动备份,清楚临时文件。
流程控制
条件选项
条件判断介绍
单分支条件
多分支条件
选择执行if语句
例子:身体质量指数(BMI)
[root@localhost code]# cat if_bmi.sh
#!/bin/bash
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
条件判断case语句
格式:
case WORD in [PATTERN [| PATTERN]...] COMMANDS ;;]... esac
case 变量引用 in
PAT1)
分支1
;;
PAT2)
分支2
;;
...
*)
默认分支
;;
esac
case支持glob风格的通配符
* 任意长度任意字符
? 仁义单个字符
[] 指定范围内的任意单个字符
| 或者,如:a|b
例子:
[root@localhost code]# cat case_yesorno.sh
#!/bin/bash
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 fails"
esac
[root@localhost code]# cat case_yesorno2.sh
#!/bin/bash
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 fails."
esac
例子:文件后缀处理
[root@localhost code]# cat suffix.sh
#!/bin/bash
read -p "Please input a file's name: " FILE
SUFFIX=`echo $FILE | grep -Eo "[^.]+$"`
case $SUFFIX in
gz)
echo gzip
;;
bz2)
echo bzip2
;;
xz)
echo xz
;;
Z)
echo compress
;;
zip)
echo zip
;;
*)
echo other
;;
esac
循环
循环执行介绍
将某代码段重复运行多次,通常有进入循环的条件和退出循环的条件
重复运行次数
- 循环次数事先已知
- 循环次数事先未知
常见的循环的命令:for,while,until
循环for
格式1:
for NAME [in WORDS ...]; do COMMANDS; done
#方式1
for 变量名 in 列表;do
循环体
done
#方式2
for 变量名 in 列表
do
循环体
done
执行机制:
1,依次将列表中的元素赋值给"变量名";每次赋值后即执行一次循环体;直到列表中的元素耗尽,循环结束
2,如果省略[in WORDS…],此时使用位置参量
for循环列表生成方式:
1,直接给出列表
2,整数列表:
{start..end}
$(seq [start [step]] end)
3,返回列表的命令
$(COMMAND)
4,使用glob,如:.sh
5,变量引用,如:
,$#
例子:面试题,计算1+2+3+…+100的结果
[root@localhost code]# sum=0;for i in {1..100};do let sum+=i;done;echo sum=$sum
sum=5050
[root@localhost code]# seq -s+ 100|bc
5050
[root@localhost code]# echo {1..100}|tr ' ' +|bc
5050
[root@localhost code]# seq 100|paste -sd +|bc
5050
例子:100以内的奇数之和
[root@localhost code]# sum=0;for i in {1..100..2};do let sum+=i;done;echo sum=$sum
sum=2500
[root@localhost code]# seq -s+ 1 2 100 | bc
2500
[root@localhost code]# echo {1..100..2}|tr ' '+ |bc
tr: missing operand after ‘ +’
Two strings must be given when translating.
Try 'tr --help' for more information.
[root@localhost code]# echo {1..100..2}|tr ' ' + |bc
2500
例子:
[root@localhost code]# ./for_sum.sh 1 2 3 4
sum=10
[root@localhost code]# cat for_sum.sh
#!/bin/bash
sum=0
for i in $*;do
let sum+=i
done
echo sum=$sum
例子:批量创建用户和并设置随机密码
[root@localhost code]# cat user_for.sh
#!/bin/bash
for i in {1..5};do
useradd user$i
PASS=`cat /dev/urandom | tr -dc '[:alnum:]'|head -c12`
echo $PASS | passwd --stdin user$i &> /dev/null
echo user$i:$PASS >> /home/hello/users/user.log
echo "user$i is created"
done
例子:九九乘法表
[root@localhost code]# ./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
[root@localhost code]# cat 99.sh
#!/bin/bash
for i in {1..9};do
for j in `seq $i`;do
echo -ne "${j}x${i}=$((i*j))\t"
done
echo
done
例子:倒叙九九乘法表
[root@localhost code]# ./99_v2.sh
1x9=9 2x9=18 3x9=27 4x9=36 5x9=45 6x9=54 7x9=63 8x9=72 9x9=81
1x8=8 2x8=16 3x8=24 4x8=32 5x8=40 6x8=48 7x8=56 8x8=64
1x7=7 2x7=14 3x7=21 4x7=28 5x7=35 6x7=42 7x7=49
1x6=6 2x6=12 3x6=18 4x6=24 5x6=30 6x6=36
1x5=5 2x5=10 3x5=15 4x5=20 5x5=25
1x4=4 2x4=8 3x4=12 4x4=16
1x3=3 2x3=6 3x3=9
1x2=2 2x2=4
1x1=1
[root@localhost code]# cat 99_v2.sh
#!/bin/bash
for i in {1..9};do
for j in $(seq `echo $[10-$i]`);do
echo -ne "${j}x`echo $[10-i]`=$(((10-i)*j))\t"
done
echo
done
生产案例:将指定目录下的文件所有文件的后缀更名为bak后缀
[root@localhost code]# cat for_rename.sh
#!/bin/bash
DIR=/data/test
for FILE in *;do
PRE=`echo $FILE|grep -Eo ".*\."`
mv $FILE $DIR/${PRE}bak
done
面试题:要求将目录YYYY-MM-DD/中所有文件,移动到YYYY-MM/DD/下
#1,创建YYYY-MM-DD格式的目录,当前日期一年前365天到目前共365个目录,里面有10个文件.log后缀的文件
[root@localhost code]# cat for_dir.sh
#!/bin/bash
PDIR=/home/hello/test
for i in {1..365};do
DIR=`date -d "-$i day" +%F`
mkdir -pv $PDIR/$DIR
cd $PDIR/$DIR
for j in {1..10};do
touch $RANDOM.log
done
done
#2,将上面的目录移动到YYYY-MM/DD/下
[root@localhost code]# cat for_dir1.sh
#!/bin/bash
DIR=/home/hello/test
cd $DIR
for subdir in *;do
YYYY_MM=`echo $subdir |cut -d"-" -f1,2`
DD=`echo $subdir |cut -d"-" -f3`
[ -d $YYYY_MM/$DD ] || mkdir -p $YYYY_MM/$DD &> /dev/null
mv $subdir/* $YYYY_MM/$DD
done
rm -rf $DIR/*-*-*
格式2:
双小括号方法,即((…))格式,也可以用于算术运算,双小括号方法也可以使bash shell实现C语言风格的变量操作
for ((: for (( exp1; exp2; exp3 )); do COMMANDS; done
for ((控制变量初始化;条件判断表达式;控制变量的修正表达式))
do
循环体
done
说明:
1,控制变量初始化:仅在运行到循环代码段时执行一次
2,控制变量的修正表达式:每轮循环结束会先进行控制变量修正运算,而后再做条件判断
例子:
[root@localhost code]# ./sum.sh
sum=5050
[root@localhost code]# cat sum.sh
#!/bin/bash
for((sum=0,i=1;i<=100;sum+=i,i++));do
true
done
echo sum=$sum
例子:九九乘法表
#语法1实现
[root@localhost code]# ./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
[root@localhost code]# cat for_99.sh
#!/bin/bash
for i in {1..9};do
for j in `seq $i`;do
echo -e "${j}x${i}=$((j*i))\t\c"
done
echo
done
#语法2实现
[root@localhost code]# ./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@localhost code]# cat for_99_2.sh
#!/bin/bash
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
- 点赞
- 收藏
- 关注作者
评论(0)