3. Shell 条件判断
重点:
条件测试。
read。
Shell 环境配置。
case。
for。
find。
xargs。
gzip,bzip2,xz。
tar。
sed。
1)Shell 的配置文件
Bash Shell 的配置文件很多,可以分成下面类别。
1.1)按 生效范围 划分两类
全局 配置:针对 所有用户 皆有效。
/etc/bashrc
/etc/profile
/etc/profile.d/*.sh
个人 配置:只针对 当前用户 有效。
~/.bash_profile
~/.bashrc
1.2)Shell 登录 两种方式 分类
1. 交互式 登录
直接通过终端输入账号密码登录。
使用 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 # 此文件执行两次
~/.bashrc
~/.bash_profile
[ 验证 执行顺序 ]
使用 Sed 命令在文件首行插入信息
// 在每个文件 "首行"
"插入 输出当前文件名称 的命令"
sed -Ei.bak '1s/^/echo .bashrc\n/' ~/.bashrc
sed -Ei.bak '1s/^/echo .bash_profile\n/' ~/.bash_profile
touch /etc/profile.d/test.sh && echo "echo /etc/profile.d/test.sh" > /etc/profile.d/test.sh
sed -Ei.bak '1s#^#echo /etc/profile\n#' /etc/profile
# 查看是否插入成功
cat ~/.bashrc | head -n 1
cat ~/.bash_profile | head -n 1
cat /etc/profile.d/test.sh | head -n 1
cat /etc/profile | head -n 1

将 命令或环境配置 放置在默认的执行文件(例如 .bashrc、.bash_profile)的不同位置,特别是最前或最后,会影响最终命令的执行顺序和生效情况。
这种情况就能够解释为什么有时候在 .bashrc 中添加的命令或配置并没有生效。原因是在其他执行文件中 比如 .bash_profile 也可能添加了相同或类似的环境配置。当不同配置文件中出现相同的配置时,后执行的配置很可能会覆盖或修改先执行的配置。这就解释了为什么前面添加的配置没有达到预期的效果。
举例来说,你在先执行的配置文件中添加了 alias g=gvim,而在后执行的配置文件中填写了 alias gv=gvim,结果是先执行的配置被后执行的配置所替代。
2. 非交互式登录
su UserName
图形界面下打开的终端
执行脚本
任何其它的 Bash 实例
执行顺序:
~/.bashrc
/etc/bashrc
/etc/profile.d/test.sh

范例:将命令放在 最前面
su root
~/.bashrc
/etc/bashrc
/etc/profile.d/test.sh
su - root
/etc/profile
/etc/profile.d/test.sh
/etc/bashrc
~/.bash_profile
~/.bashrc
/etc/bashrc

范例:将命令放在 最后面
默认配置文件 执行顺序
su - root
/etc/profile.d/test.sh
/etc/bashrc
/etc/profile
/etc/bashrc
~/.bashrc
~/.bash_profile
su root
/etc/profile.d/test.sh
/etc/bashrc
~/.bashrc
1.3)按 功能划分 分类
profile 类 和 bashrc 类
1. Profile 类
profile 类 为交互式登录的 Shell 提供配置。
全局: /etc/profile /etc/profile.d/*.sh
个人: ~/.bash_profile
常用于:
(1) 建议:用于定义环境变量。
(2) 建议:运行全局命令或脚本。
2. Bashrc 类
Bashrc 类:为非交互式和交互式登录的 Shell 提供配置。
全局: /etc/bashrc
个人: ~/.bashrc
常用于:
(1) 建议:定义命令别名和函数。
(2) 建议:定义本地变量。
1.4)编辑配置文件生效
修改 Profile 和 Bashrc 文件后 使其生效的两种方法。
重新启用 Shell 进程
source 配置文件
注意:source 会在当前 Shell 中执行脚本,所以一般只用于执行配置文件,或在脚本中调用另一个脚本的场景。
范例:
source ~/.bashrc
1.5)Bash 退出任务
编辑 ~/.bash_logout 文件(用户环境),在退出 Shell 时运行。
常用于:
1. 创建自动备份
2. 清除临时文件
[ 举例 ]
touch /data/1.txt /data/2.txt
ls /data

编辑 ~/.bash_logout 文件(用户环境),在退出 Shell 时运行。
vim ~/.bash_logout
rm -rf /data/*

[ 退出终端,自动执行 ~/.bash_logout 中的命令 ]

[ 案例 ]
这个命令的含义是将一个空字符串写入用户的 .bash_history 文件中,从而清空命令历史记录。
vim ~/.bash_logout
# ~/.bash_logout
echo ' ' > ~/.bash_history

1.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!”
vim /etc/motd
4、编写生成脚本基本格式的脚本,包括作者,联系方式,版本,时间,描述等。
2)流程控制
2.1)条件选择
2.1.1)条件判断分支
1. 单分支 条件
[ 之前学到的 短路与 短路或 其实也是可以做到的 ]
如:CMD1 && CMD2 || exit;

2. 双分支 条件
[ 之前学到的 短路与 短路或 其实也是可以做到的 ]
如:CMD && CMD2 || CMD3

2. 多分支 条件

在 Shell 语言中,"if" 是一个关键字,用于控制流程和条件判断。
type if

2.1.2)选择执行 if 语句
说明:多个条件时,逐个条件进行判断,第一次遇为 "真" 条件时,执行其分支,而后结束整个 if 语句。
-- 单分支 --
if CMD1; then
CMD2
fi
-- 双分支 --
# CMD && CMD2 || CMD3
if CMD1; then
CMD2
else
CMD3
fi
-- 多分支 --
if CMD1; then
CMD2
elif CMD3; then
CMD4
elif CMD5; then
CMD6
...
else
CMDn
fi
单分支
if 判断条件; then
条件为真的分支代码
fi
双分支
if 判断条件; then
条件为真的分支代码
else
条件为假的分支代码
fi
多分支
if 判断条件1; then
条件1为真的分支代码
elif 判断条件2; then
条件2为真的分支代码
elif 判断条件3; then
条件3为真的分支代码
...
else
以上条件都为假的分支代码
fi
[ 案例 1 ]
vim if_bmi.sh
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

[ 案例 2 ]
手动将如下脚本内容;修改为使用条件分支形式执行。
-- 修改前 --
#!/bin/bash
read -p "石头-0 剪刀-1 布-2 请出拳: " choose
[[ ! $choose =~ ^[0-9]+$ ]] && { echo "要输入正确的数字" && exit; }
[ $choose -eq 0 ] && { echo "你出的是石头" && exit; }
[ $choose -eq 1 ] && { echo "你出的是剪刀" && exit; }
[ $choose -eq 2 ] && { echo "你出的是布" && exit; }
echo "你搁着瞎出是吧???"
-- 修改后 --
#!/bin/bash
read -p "石头-0 剪刀-1 布-2 请出拳: " choose
[[ ! $choose =~ ^[0-9]+$ ]] && { echo "要输入正确的数字" && exit; }
if [ $choose -eq 0 ]; then
echo "你出的是石头"
exit
elif [ $choose -eq 1 ]; then
echo "你出的是剪刀"
exit
elif [ $choose -eq 2 ];then
echo "你出的是布"
exit
else
echo "你搁着瞎出是吧???"
fi

2.1.3)条件判断 case 语句
格式
case 变量引用 in
PAT1)
分支1
;;
PAT2)
分支2
;;
...
*)
默认分支
;;
esac
case 支持 glob 风格的通配符:
* 任意长度任意字符
? 任意单个字符
[] 指定范围内的任意单个字符
| 或者, 如: a|b
[ 案例 1 ]
tr 'A-Z' 'a-z':这部分代码使用了 tr 命令,它用于 字符转换。
在这里,'A-Z' 表示大写字母的范围,'a-z' 表示相应的小写字母的范围。
因此,这个命令会将 $INPUT 中的所有大写字母转换为对应的小写字母。
vim yesorno.sh
#!/bin/bash
read -p "Are you OK?(yes/no)? " INPUT
# 重要: 将 INPUT 值转换为小写
# 利于后续判断 [ 后续判断值: 是否为 y or yes ]
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

如果不转换大小写,也可以使用如下方式:
[yY]|[Yy][Ee][Ss]):用于匹配用户输入是否是 "y"、"Y"、"yes"、"Yes" 等任何这些组合。
如果用户的输入匹配了这个模式,接下来的代码块将被执行。
[Nn]|[Nn][Oo]):用于匹配用户输入是否是 "n"、"N"、"no"、"No" 等任何这些组合。
vim yesorno.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 fales,please input yes or no!"
esac

[ 优化脚本 1 ]
$[RANDON%3]:表示对 3 取模,也就是 0,1,2。
生成一个随机整数,然后对该随机整数进行模 3 操作,得到的结果是 0、1 或 2 中的一个。
综合起来,整个条件表达式是在检查三种不同的情况:
[ 你 出拳胜出 的情况,有如下三种。]
choose 为 0 且 result 为 1;
choose 为 1 且 result 为 2;
choose 为 2 且 result 为 0。
#!/bin/bash
read -p "石头-0 剪刀-1 布-2 请出拳: " choose
[[ ! $choose =~ ^[0-9]+$ ]] && { echo "要输入正确的数字" && exit; }
# 随机取模
result=$[RANDOM%3]
# 判断
# -a 这是逻辑运算符"and" 用于将两个条件连接, 表示两个条件都必须为真。
# -o 这是逻辑运算符 "or" 用于将两个条件连接, 表示两个条件中只要有一个为真即可。
if [ $choose -eq 0 -a $result -eq 1 -o $choose -eq 1 -a $result -eq 2 -o $choose -eq 2 -a $result -eq 0 ];then
echo 你出拳 $choose
echo 机器人出拳 $result
echo "你胜出"
elif [ $choose -eq $result ]; then
echo 你出拳 $choose
echo 机器人出拳 $result
echo "平局,再来!"
exit
else
echo 你出拳 $choose
echo 机器人出拳 $result
echo "你输啦!"
fi

[ 优化脚本 2 ]
使用 case 将 输入信息 转化为 中文字符
#!/bin/bash
read -p "石头-0 剪刀-1 布-2 请出拳: " choose
[[ ! $choose =~ ^[0-9]+$ ]] && { echo "要输入正确的数字" && exit; }
# 随机取模
result=$[RANDOM%3]
# 将 输入信息 转化为 中文字符
case $choose in
0)
choose="石头"
;;
1)
choose="剪刀"
;;
2)
choose="布"
;;
*)
echo"输入有误"
exit
;;
esac
# 将 随机数信息 转化为 中文字符
case $result in
0)
result="石头"
;;
1)
result="剪刀"
;;
2)
result="布"
;;
esac
echo -e "\E[1;32m----------------\E[0m"
# 判断
# -a 这是逻辑运算符"and" 用于将两个条件连接, 表示两个条件都必须为真。
# -o 这是逻辑运算符 "or" 用于将两个条件连接, 表示两个条件中只要有一个为真即可。
if [ $choose == "石头" -a $result == "剪刀" -o $choose == "剪刀" -a $result == "布" -o $choose == "布" -a $result == "石头" ];then
echo 你出拳 $choose
echo 机器人出拳 $result
echo -e "\E[1;32m你胜出!\E[0m"
elif [ $choose == $result ]; then
echo 你出拳 $choose
echo 机器人出拳 $result
echo "平局,再来!"
exit
else
echo 你出拳 $choose
echo 机器人出拳 $result
echo -e "\E[1;31m你输啦!\E[0m"
fi

2.1.4)运维菜单 实现版本 2
#!/bin/bash
echo -en "\E[$[RANDOM%7+31];1m"
cat <<EOF
请选择:
1)备份数据库
2)清理日志
3)软件升级
4)软件回滚
5)删库跑路
EOF
echo -en '\E[0m'
read -p "请输入上面数字 1-5: " MENU
case $MENU in
1)
echo "执行备份数据库"
#./backup.sh
;;
2)
echo "清理日志"
;;
3)
echo "软件升级"
;;
4)
echo "软件回滚"
;;
5)
echo "删库跑路"
;;
*)
echo "INPUT FALSE!"
esac

3)练习题
1、编写脚本 createuser.sh,实现如下功能:使用一个用户名做为参数,如果指定参数的用户存在,就显示其存在,否则添加之。并设置初始密码为123456,显示添加的用户的 id 号等信息,在此新用户第一次登录时,会提示用户立即改密码,如果没有参数,就提示:请输入用户名。
#!/bin/bash
# 检查是否提供了用户名作为参数
if [ $# -ne 1 ]; then
echo "请输入用户名"
exit 1
fi
username="$1"
# 检查用户是否已存在
if id "$username" &>/dev/null; then
echo "用户 $username 已存在"
else
# 创建用户,设置初始密码为123456
useradd "$username"
echo "用户 $username 添加成功"
echo "初始密码已设置为 123456"
# 修改用户密码,要求用户在第一次登录时更改密码
echo "$username:123456" | chpasswd
echo "用户 $username 的密码将在第一次登录时更改"
fi
2、编写脚本 yesorno.sh,提示用户输入 yes 或 no,并判断用户输入的是 yes 还是 no,或是其它信息。
#!/bin/bash
# 提示用户输入
read -p "请输入 'yes' 或 'no': " user_input
# 检查用户输入
if [ "$user_input" == "yes" ]; then
echo "你输入了 'yes'"
elif [ "$user_input" == "no" ]; then
echo "你输入了 'no'"
else
echo "你输入了其他信息"
fi
3、编写脚本 filetype.sh,判断用户输入文件路径,显示其文件类型(普通,目录,链接,其它文件类型)
#!/bin/bash
# 提示用户输入文件路径
read -p "请输入文件路径: " file_path
# 检查文件类型
if [ -e "$file_path" ]; then
if [ -f "$file_path" ]; then
echo "这是一个普通文件"
elif [ -d "$file_path" ]; then
echo "这是一个目录"
elif [ -L "$file_path" ]; then
echo "这是一个符号链接"
else
echo "这是其他文件类型"
fi
else
echo "文件不存在或路径无效"
fi
4、编写脚本 checkint.sh,判断用户输入的参数是否为正整数。
#!/bin/bash
# 提示用户输入参数
read -p "请输入一个参数: " user_input
# 使用正则表达式检查是否为正整数
if [[ $user_input =~ ^[0-9]+$ ]] && [ "$user_input" -gt 0 ]; then
echo "输入的参数是正整数"
else
echo "输入的参数不是正整数"
fi
5、编写脚本 reset.sh,实现系统安装后的初始化环境。
包括:
1、别名
2、环境变量,如 PS1 等
3、安装常用软件包,如:tree
5、实现固定的 IP 的设置,
6、Vim 的设置等。
#!/bin/bash
# Check if the script is running with root privileges
if [ "$EUID" -ne 0 ]; then
echo "Please run this script as root."
exit 1
fi
# Detect the Linux distribution
if [ -f /etc/redhat-release ]; then
DISTRO="centos"
elif [ -f /etc/lsb-release ]; then
DISTRO="ubuntu"
else
echo "Unsupported Linux distribution."
exit 1
fi
# Function to install packages based on the Linux distribution
install_packages() {
if [ "$DISTRO" == "centos" ]; then
yum install -y $@
elif [ "$DISTRO" == "ubuntu" ]; then
apt-get update
apt-get install -y $@
fi
}
# Set environment variables
cat <<EOL >> ~/.bashrc
# Custom PS1 prompt
PS1="\[\e[1;32m\][\t \[\e[1;33m\]\u\[\e[35m\]@\h\[\e[1;31m\] \W\[\e[1;32m\]]\\[\e[0m\]\\$ "
EOL
# Create aliases
cat <<EOL >> ~/.bashrc
# Custom Aliases
alias ll='ls -la'
alias tree='tree -C'
EOL
# Install essential software
install_packages tree vim git net-tools lrzsz
# Set a static IP address (modify with your network settings)
if [ "$DISTRO" == "centos" ]; then
cat <<EOL >> /etc/sysconfig/network-scripts/ifcfg-eth0
BOOTPROTO=static
IPADDR=192.168.1.100
NETMASK=255.255.255.0
GATEWAY=192.168.1.1
DNS1=8.8.8.8
EOL
systemctl restart network
elif [ "$DISTRO" == "ubuntu" ]; then
cat <<EOL >> /etc/netplan/01-netcfg.yaml
network:
version: 2
renderer: networkd
ethernets:
eth0:
addresses:
- 192.168.1.100/24
gateway4: 192.168.1.1
nameservers:
addresses: [8.8.8.8]
EOL
netplan apply
fi
# Vim configuration
cat <<EOL >> ~/.vimrc
" Vim configuration
syntax on
set number
set tabstop=4
set shiftwidth=4
set expandtab
EOL
echo "Initialization completed. Please log out and log back in for changes to take effect."
3. Shell 条件判断的更多相关文章
- [Shell]条件判断与流程控制:if, case, for, while, until
---------------------------------------------------------------------------------------------------- ...
- shell条件判断if中的-a到-z的意思
[ -a FILE ] 如果 FILE 存在则为真. [ -b FILE ] 如果 FILE 存在且是一个块特殊文件则为真. [ -c FILE ] 如果 FILE 存在且是一个字特殊文件则 ...
- shell条件判断与流程控制
一 条件判断式语句 1.按文件类型进行判断 测试类型 作用 -b 文件 判断文件是否存在,并且是否为块设备文件(是块设备文件为真) -c 文件 判断文件是否存在,并且是否为字符设备文件(是字符设备设备 ...
- shell 条件判断语句整理
常用系统变量 1) $0 当前程式的名称 2) $n 当前程式的第n个参数,n=1,2,…9 3) $* 当前程式的任何参数(不包括程式本身) 4) ...
- LINUX SHELL条件判断
算术运算的条件判断 [] [[]]: -eq -ne -lt -le -gt -ge (( )):><>=<== [root@monitor ~]# if (( 2 == 3) ...
- Shell条件判断(6)- 多重条件判断
多重条件判断 多个条件判断一起使用 测试选项 作用 判断1 -a 判断2 逻辑与,判断1和判断2都成立,最终的结果才为真 判断1 -o 判断2 逻辑或,判断1和判断2有一个成立,最终的结果就为真 ! ...
- linux shell 条件判断if else, if elif else....
在linux的shell中 if 语句通过关系运算符判断表达式的真假来决定执行哪个分支.Shell 有三种 if ... else 语句: if ... fi 语句: if ... else ... ...
- shell条件判断
1.字符串判断 str1 = str2 当两个串有相同内容.长度时为真 str1 != str2 当串str1和str2不等时为真 -n str1 当串的长度大于0时为真(串非空) -z str1 当 ...
- 学习 shell —— 条件判断 if 的参数
1. 文件判断表达式 -e filename:如果 filename 存在(exist),则为真: -d filename:如果 filename 为目录(directory),则为真: -f fil ...
- shell 条件判断
一.数值判断 INT1 -eq INT2 INT1和INT2两数相等为真 INT1 -ne INT2 INT1和INT2两数不等为真 INT1 -gt INT2 ...
随机推荐
- 原来ES7~12分别增加了这些属性呀
ES6也称为ES2015,于2015年发布,此后每年都有新增一些属性,分别命名为ES7~12,发布的年份分别对应2016年到2021年 ES7 includes方法 数组中新增了includes方法, ...
- Matlab机器人工具箱安装教程
参考以下博客 https://blog.csdn.net/AprilsHell/article/details/90722892
- [Lua] IT技术熟练度生成器 | 根据IT活动记录生成md表格 | 自创
IT技术熟练度 v1.0 为衡量个人能力水平自创的一套评分机制,根据时间.代码行数.基础理论三个变量生成.最近在学lua,正好练下基本功.效果可见 个人介绍 | 代码统计 - 小能日记 - 博客园 ( ...
- 11、Spring之基于注解的AOP
11.1.环境搭建 创建名为spring_aop_annotation的新module,过程参考9.1节 11.1.1.配置打包方式和依赖 注意:AOP需要在IOC的基础上实现,因此需要导入IOC的依 ...
- 三维模型OSGB格式轻量化压缩点云处理技术探讨
三维模型OSGB格式轻量化压缩点云处理技术探讨 点云是一种常用的三维模型表示方法,由于其具有高精度.高保真度.易处理等优点,因此在很多领域都得到了广泛应用.但是,点云数据的存储量通常比较大,为了使点云 ...
- 【故障公告】一而再,再而三,三翻四复:数据库服务器 CPU 100%
会员救园,故障捣乱,每当困难时,故障们总是喜欢雪上加霜过来考验你. 今天下班前 17:43~17:47 期间,园子的 SQL Server 数据库服务器突然出现 CPU 100% 问题. 发现问题后, ...
- KRPano中文教程文档PDF版本下载
KRPano中文教程文档PDF版本下载 下载地址:https://pan.baidu.com/s/1qXIZ2os 感谢KRPano技术解密群小伙伴:斌仔分享 中文文档目录: 概述文件说明krpano ...
- 修改经过Spring Gateway的Json数据
背景 使用Spring Cloud Gateway作为网关时经常会需要对报文内的json数据进行修改,但是目前看到的实现方法看起来都很复杂,这里提供一种使用Spring官方提供的ModifyReque ...
- 在阿里云和腾讯云的轻量应用服务器上搭建Hadoop集群
引入 本文在两台2核2g的云服务器上搭建了Hadoop集群,两台云服务器分别是阿里云(hjm)和腾讯云(gyt),集群部署规划如下: hjm gyt HDFS NameNode\SecondaryNa ...
- dedebiz数据重置
TRUNCATE biz_addonarticle;TRUNCATE biz_addonimages;TRUNCATE biz_addoninfos;TRUNCATE biz_addonshop;TR ...