重点:

条件测试。

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 条件判断的更多相关文章

  1. [Shell]条件判断与流程控制:if, case, for, while, until

    ---------------------------------------------------------------------------------------------------- ...

  2. shell条件判断if中的-a到-z的意思

    [ -a FILE ]  如果 FILE 存在则为真.  [ -b FILE ]  如果 FILE 存在且是一个块特殊文件则为真.  [ -c FILE ]  如果 FILE 存在且是一个字特殊文件则 ...

  3. shell条件判断与流程控制

    一 条件判断式语句 1.按文件类型进行判断 测试类型 作用 -b 文件 判断文件是否存在,并且是否为块设备文件(是块设备文件为真) -c 文件 判断文件是否存在,并且是否为字符设备文件(是字符设备设备 ...

  4. shell 条件判断语句整理

    常用系统变量 1)         $0 当前程式的名称 2)         $n 当前程式的第n个参数,n=1,2,…9 3)         $* 当前程式的任何参数(不包括程式本身) 4)   ...

  5. LINUX SHELL条件判断

    算术运算的条件判断 [] [[]]: -eq -ne -lt -le -gt -ge (( )):><>=<== [root@monitor ~]# if (( 2 == 3) ...

  6. Shell条件判断(6)- 多重条件判断

    多重条件判断 多个条件判断一起使用 测试选项 作用 判断1 -a 判断2 逻辑与,判断1和判断2都成立,最终的结果才为真 判断1 -o 判断2 逻辑或,判断1和判断2有一个成立,最终的结果就为真 ! ...

  7. linux shell 条件判断if else, if elif else....

    在linux的shell中 if 语句通过关系运算符判断表达式的真假来决定执行哪个分支.Shell 有三种 if ... else 语句: if ... fi 语句: if ... else ... ...

  8. shell条件判断

    1.字符串判断 str1 = str2 当两个串有相同内容.长度时为真 str1 != str2 当串str1和str2不等时为真 -n str1 当串的长度大于0时为真(串非空) -z str1 当 ...

  9. 学习 shell —— 条件判断 if 的参数

    1. 文件判断表达式 -e filename:如果 filename 存在(exist),则为真: -d filename:如果 filename 为目录(directory),则为真: -f fil ...

  10. shell 条件判断

    一.数值判断 INT1 -eq INT2           INT1和INT2两数相等为真 INT1 -ne INT2           INT1和INT2两数不等为真 INT1 -gt INT2 ...

随机推荐

  1. js中的函数式编程

    函数是javascript中非常重要的一部分,用途也非常的多,可作为参数.返回值.回调等等,下面有一些函数式编程的重要概念和定义 纯函数 纯函数属于程序设计的名词,其它语言中也是存在的,而在javas ...

  2. 领域驱动设计(DDD):从基础代码探讨高内聚低耦合的演进

    大家好,我是付威,一名已在编码第一线奋斗了十余年的程序员.在2019年我初次接触到领域驱动设计(Domain-Driven Design,简称DDD)的概念.在我的探索中,我发现许多有关DDD的教程过 ...

  3. 04.使用 github actions+docker 自动部署前后端分离项目 zhontai (.net core+vue)

    前言 Github Actions是什么?是 GitHub 提供的一种持续集成/持续部署(CI/CD)工作流程自动化服务,助力项目的自动化构建.测试和部署. 依托于平台,本文将分享使用 GitHub ...

  4. LeetCode952三部曲之二:小幅度优化(137ms -> 122ms,超39% -> 超51%)

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 本文是<LeetCode952三部曲& ...

  5. 谈谈JSF业务线程池的大小配置

    1.简介 JSF业务线程池使用JDK的线程池技术,缺省情况下采用Cached模式(核心线程数20,最大线程数200).此外,还提供了Fixed固定线程大小的模式,两种模式均可设置请求队列大小. 本文旨 ...

  6. 一次性全讲透GaussDB(DWS)锁的问题

    本文分享自华为云社区<GaussDB(DWS)锁问题全解>,作者: yd_211043076. 一.gaussdb有哪些锁 1.常规锁:常规锁主要用于业务访问数据库对象的加锁,保护并发操作 ...

  7. 拉普拉斯金字塔在多图HDR算法中的应用以及多曝光图像的融合算法简介。

    在SSE图像算法优化系列二十九:基础的拉普拉斯金字塔融合用于改善图像增强中易出现的过增强问题(一) 一文中我们曾经描述过基于几种高频融合法则的拉普拉斯金字塔融合算法,那里是主要针对2副图像的.实际的应 ...

  8. 西门子Teamcenter 许可分析

    西门子Teamcenter 许可 绑定了主机名称,mac地址 另外,Teamcenter可以支持多个许可服务 所以.......................找个正式许可复制就可以 end succ ...

  9. salesforce零基础学习(一百三十二)Flow新功能: Custom Error

    本篇参考: https://help.salesforce.com/s/articleView?id=sf.flow_ref_elements_custom_error.htm&type=5 ...

  10. c语言代码练习3改进

    #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> int main() { int x = 0; printf("请输入一 ...