shell脚本编程实践第2天
1 内容格式化
1.1 输出格式化
1.1.1 echo解读
学习目标
这一节,我们从 基础知识、简单实践、小结、三个方面来学习。
基础知识
命令简介
echo命令的功能是将内容输出到默认显示设备,一般起到一个提示的作用。
OPTIONS:
-n 不要在最后自动换行
-e 若字符串中出现以下字符,则特别加以处理,而不会将它当成一般文字输出:转义字符
\a 发出警告声;
\b 删除前一个字符;
\c 最后不加上换行符号;
\f 换行但光标仍旧停留在原来的位置;
\n 换行且光标移至行首;
\r 光标移至行首,但不换行;
\t 插入tab;
\v 与\f相同;
\ 插入\字符;
\0nnn 打印nnn(八进制)所代表的ASCII字符; 备注:数字0 不要理解成字母o
\xNN 打印NN(十六进制)所代表的ASCII字符;-–help 显示帮助
-–version显示版本信息
简单实践
实践1 - 信息的输出
echo后边用单引号包围要添加的内容
[root@localhost ~]# echo 'hello world' >> /tmp/hello.txt
[root@localhost ~]# cat /tmp/hello.txt
hello world
实践2 - 引号信息输出
通过引号的错开实现引号的输出
[root@localhost ~]# echo "I'm a king of the world."
I'm a king of the world.
实践3 - 特殊符号的输出
使用 -e 选项启用转义字符的解析
[root@localhost ~]# echo -e "The 2021 State of DevOps Report\n\t- is here"
The 2021 State of DevOps Report- is here
实践4 - 内容的拼接
使用 -n 选项启用信息输出不换行
[root@localhost ~]# echo -n hello;echo world
helloworld
小结
1.1.2 字体颜色
学习目标
这一节,我们从 基础知识、简单实践、小结 三个方面来学习。
基础知识
场景需求
echo本质上是将信息内容输出到当前的屏幕终端,如果只是一种颜色的话,可能导致视觉疲劳。所以,一般情况下,我们在显示信息的时候,往往会通过颜色的方式实现特定内容的颜色高亮显示。echo命令可以修改字体类型,字体背景色以及字体颜色,转义序列\033可以用于改变字体属性。
格式解读
格式如下:echo -e "\033[字背景颜色;文字颜色m字符串\033[0m"echo -e "\033[41;36m 显示的内容 \033[0m"
颜色分类
色彩 | 黑 | 红 | 绿 | 黄 | 蓝 | 紫 | 青 | 灰 |
---|---|---|---|---|---|---|---|---|
字体色 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 |
背景色 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 |
结束控制符
最后面控制选项说明\033[0m 关闭所有属性 \033[1m 设置高亮度 \033[4m 下划线\033[5m 闪烁 \033[7m 反显 \033[8m 消隐
注意:\033 是八进制的ESCAPE字符,我们可以用 \e 来代替
简单实践
实践1 - 字体颜色和背景颜色
字体颜色示例
echo -e "\033[30m 黑色字 \033[31m 红色字 \033[32m 绿色字 \033[33m 黄色字 \033[0m"
echo -e "\033[34m 蓝色字 \033[35m 紫色字 \033[36m 天蓝字 \033[37m 白色字 \033[0m"背景颜色示例
echo -e "\033[40;37m 黑底白字 \033[41;37m 红底白字 \033[42;37m 绿底白字 \033[0m"
echo -e "\033[43;37m 黄底白字 \033[44;37m 蓝底白字 \033[45;37m 紫底白字 \033[0m"
echo -e "\033[46;37m 天蓝底白字 \033[47;30m 白底黑字 \033[0m"
实践2 - 信息颜色显示
定制堡垒机的测试页面脚本
[root@localhost ~]# cat simple_jumpserver.sh
#!/bin/bash
# 功能:定制堡垒机的展示页面
# 作者:wangshuji
# 版本:V0.1
# 联系:superopsmsb.comecho -e "\e[31m \t\t 欢迎使用堡垒机"echo -e "\e[32m
-----------请选择你要登录的远程主机-----------1: 10.0.0.14 (nginx)2: 10.0.0.15 (tomcat)3: 10.0.0.19 (apache)q: 使用本地主机
----------------------------------------------
"'\033[0m'
echo -e "请输入您要选择的远程主机编号: "
小结
1.1.3 printf格式化
学习目标
这一节,我们从 基础知识、简单实践、小结 三个方面来学习。
基础知识
场景需求
虽然我们能够通过 echo的方式实现信息某种程度的格式化输出,但是很多信息的输出偏重于手工的干预,效率太慢。我们需要一种功能更强大、效率更高的格式化手段。-- printf
printf简介
printf 命令模仿 C 程序库(library)里的 printf() 程序。由于 printf 由 POSIX 标准所定义,因此使用 printf 的脚本比使用 echo 移植性好。printf 使用引用文本或空格分隔的参数,外面可以在 printf 中使用格式化字符串,还可以制定字符串的宽度、左右对齐方式等。默认 printf 不会像 echo 自动添加换行符,我们可以手动添加 \n。
基本语法
查看帮助
[root@localhost ~]# help printf
printf: printf [-v var] 格式 [参数]
格式化替换符%s 字符串%d,%i 十进制整数%f 浮点格式%c ASCII字符,即显示对应参数的第一个字符%b 相对应的参数中包含转义字符时,可以使用此替换符进行替换,对应的转义字符会被转义%o 八进制值%u 不带正负号的十进制值%x 十六进制值(a-f)%X 十六进制值(A-F)%% 表示%本身
格式化转义符号\a 警告字符,通常为ASCII的BEL字符\b 后退\c 抑制(不显示)输出结果中任何结尾的换行字符\f 换页(formfeed)\n 换行\r 回车(Carriage return)\t 水平制表符\v 垂直制表符\\ 一个字面上的反斜杠字符\ddd 表示1到3位数八进制值的字符。仅在格式字符串中有效\0ddd 表示1到3位的八进制值字符
格式化字符解释
– 将字段里已格式化的值向左对齐
空格 在正值前置一个空格,在负值前置一个负号
+ 总是在数值之前放置一个正号或负号,即便是正值也是
# 下列形式选择其一:%o有一个前置的o; %x与%X分别前置的0x与0X;%e,%E与%f总是在结果中有一个小数点; %g与%G为没有结尾的零。
0 以零填补输出,而非空白.这仅发生在字段宽度大于转换后的情况
简单实践
实践1 - 命令演示
普通echo命令演示换行信息和非换行信息
[root@localhost ~]# echo "Hello, Shell Base"
Hello, Shell Base
[root@localhost ~]# echo -n "Hello, Shell Base"
Hello, Shell Base[root@localhost ~]#printf命令演示换行信息和非换行信息
[root@localhost ~]# printf "Hello, Shell Base\n"
Hello, Shell Base
[root@localhost ~]# printf "Hello, Shell Base"
Hello, Shell Base[root@localhost ~]#
实践2 - 替换符号演示
基本信息演示 - 单引号和双引号效果一样
[root@localhost ~]# printf "姓名:%s, 语文:%d, 数学:%d\n" "张三" 89 98
姓名:张三, 语文:89, 数学:98
[root@localhost ~]# printf '姓名:%s, 语文:%d, 数学:%d\n' "张三" 89 98
姓名:张三, 语文:89, 数学:98
注意:相关信息会按照顺序依次替换到格式化的替换符位置
数字格式展示
[root@localhost ~]# printf '姓名:%s, 身高:%f米, 体重:%f公斤\n' "张三" 1.7 66
姓名:张三, 身高:1.700000米, 体重:66.000000公斤
[root@localhost ~]# printf '姓名:%s, 身高:%.2f米, 体重:%.1f公斤\n' "张三" 1.7 66
姓名:张三, 身高:1.70米, 体重:66.0公斤
注意:通过 %.nf,n代表小数点后面的可显示的位数。
实践3 - 简单格式化
() 用于信息的批量化显示
[root@localhost ~]# printf "(%d %s)\n" 1 张三 2 李四 3 王五
(1 张三)
(2 李四)
(3 王五)printf默认不携带最后的换行
[root@localhost ~]# printf "(%d %s) " 1 张三 2 李四 3 王五
(1 张三) (2 李四) (3 王五) [root@localhost ~]#借助于echo的功能实现换行的效果
[root@localhost ~]# printf "(%d %s) " 1 张三 2 李四 3 王五; echo
(1 张三) (2 李四) (3 王五)
实践4 - 格式化补充
%s字符串格式化
[root@localhost ~]# printf '姓名:%-10s语文:%d, 数学:%d\n' "张三" 89 98 "李四" 87 97
姓名:张三 语文:89, 数学:98
姓名:李四 语文:87, 数学:97
注意:%-10s,代表信息后面携带10个空格,便于格式化
%d数字格式补全
[root@localhost ~]# printf "%5d %s\n" 1 张三1 张三
[root@localhost ~]# printf "%05d %s\n" 1 张三
00001 张三
[root@localhost ~]# printf "%05d %s\n" 100 张四
00100 张四
注意:0的作用就是不用空格补全,而是用0填充,实现格式化
实践5 - 环境变量的使用
定制环境变量
[root@localhost ~]# VAR1=hello; VAR2=shell颜色显示
[root@localhost ~]# printf "\033[32m%s \033[31m%s\033[0m\n" $VAR1 $VAR2
hello shell
小结
1.1.4 综合案例
学习目标
这一节,我们从 java部署、脚本定制、小结 三个方面来学习。
java部署
准备工作
创建目录
mkdir /data/{softs,server} -p
cd /data/softs下载java或者上传java
ls /data/softs
安装java
tar xf jdk-8u121-linux-x64.tar.gz -C /data/server
cd /data/server/
ln -s jdk1.8.0_121 java
配置java环境变量
echo 'export JAVA_HOME=/data/server/java' >> /etc/profile.d/java.sh
echo 'export PATH=$JAVA_HOME/bin:$PATH' >> /etc/profile.d/java.sh
source /etc/profile.d/java.sh检查效果
java -version
手工清理环境
rm -f /etc/profile.d/java.sh
rm -rf /data/server/java /data/server/jdk1.8.0_121
信息显示
定制java环境部署脚本
[root@localhost ~]# cat /data/scripts/java_install.sh
#!/bin/bash
# 功能: java环境的定制
# 版本:v0.1
# 作者:书记
# 联系:www.superopsmsb.com# 定制基本信息
JAVA_SOFT='jdk-8u121-linux-x64.tar.gz'
JAVA_DIR='jdk1.8.0_121'
JAVA_NAME='java'
SERVER_HOME='/data/server'
SOFTS_HOME='/data/softs'
RED="echo -e \E[1;31m"
END="\E[0m"# 安装软件
tar xf $SOFTS_HOME/$JAVA_SOFT -C $SERVER_HOME
ln -s $SERVER_HOME/$JAVA_DIR $SERVER_HOME/$JAVA_NAME# 定制环境变量
cat > /etc/profile.d/java.sh << EOF
export JAVA_HOME=$SERVER_HOME/$JAVA_NAME
export PATH=\$JAVA_HOME/bin:\$PATH
EOF# 加载java环境变量文件
source /etc/profile.d/java.sh# 检查效果
java -version > /tmp/txt 2>&1
java_version=$(grep version /tmp/txt | cut -d '"' -f2)
runtime_version=$(grep Runtime /tmp/txt | cut -d ' ' -f6 | cut -d ")" -f1)
jvm_type=$(grep VM /tmp/txt | cut -d " " -f8)# 信息显示
$RED---------$JAVA_NAME软件运行情况---------$END
printf "\033[32m%s:\033[33m%s\033[0m\n" "java软件版本" $java_version
printf "\033[32m%s:\033[33m%s\033[0m\n" "java运行时环境版本" $runtime_version
printf "\033[32m%s:\033[33m%s\033[0m\n" "jvm运行模式" $jvm_type
$RED----------------------------------$END
小结
2 脚本交互
2.1 基础知识
2.1.1 shell登录解读
学习目标
这一节,我们从 基础知识、简单实践、小结 三个方面来学习。
基础知识
shell配置文件
系统级别生效配置文件/etc/profile系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行/etc/profile.d/*.sh被/etc/profile文件调用,执行当前目录下所有的文件中关于shell的设置/etc/bashrc为每一个运行bash shell的用户执行此文件.当bash shell被打开时,该文件被读取。
用户级别生效配置文件~/.bash_profile设定用户专用的shell信息,当用户登录时,该文件仅仅执行一次~/.bashrc该文件包含用户专用的bash信息,当登录时以及每次打开新的shell时,该文件被读取
用户退出生效配置文件~/.bash_logout: 当每次退出系统(退出bash shell)时,执行该文件.~/.bash_history: 用户登录时自动读取其中的内容并加载到内存hiatory记录中logout时将内存中的history记录写入该文件中
shell的登录方式
交互式登录方法1:密码登录直接通过终端输入账号密码登录复制终端方法2:su 变更shell操作用户的身份su - 用户名超级用户除外,需要键入该使用者的密码。
非交互式登录方法1:脚本执行方法2:su 用户名
登录shell的文件生效流程/etc/profile.d/*.sh-> /etc/profile-> /etc/bashrc-> ~/.bashrc-> ~/.bash_profile
非登录shell的文件生效流程/etc/profile.d/*.sh-> /etc/bashrc-> ~/.bashrc
注意:若多配置文件中设置相同的变量,则后面配置文件中变量的值会覆盖前面配置文件中同一变量的值。
su的相关参数-:当前用户不仅切换为指定用户的身份,同时所用的工作环境也切换为此用户的环境。-l:同 - 的使用类似,完整切换工作环境,后面需要添加欲切换的使用者账号。-p:表示切换为指定用户的身份,但不改变当前的工作环境(不使用切换用户的配置文件)。-m:和 -p 一样;-c 命令:仅切换用户执行一次命令,执行后自动切换回来,该选项后通常会带有要执行的命令。
配置文件修改后生效的方法
修改profile和bashrc文件后需生效两种方法1. 重新启动shell进程2. source|. 配置文件注意:source 会在当前shell中执行脚本,所有一般只用于执行置文件,或在脚本中调用另一个脚本的场景
简单实践
准备工作
为所有的shell相关的配置文件添加关键信息
echo "echo '1 - /etc/profile'" >> /etc/profile
echo "echo '2 - /etc/profile.d/2.sh'" >> /etc/profile.d/2.sh
echo "echo '3 - /etc/bashrc'" >> /etc/bashrc
echo "echo '4 - ~/.bash_profile'" >> ~/.bash_profile
echo "echo '5 - ~/.bashrc'" >> ~/.bashrc
非登录效果
[root@localhost ~]# su - python
上一次登录:五 6月 10 16:16:37 CST 2022pts/1 上
2 - /etc/profile.d/2.sh
1 - /etc/profile
3 - /etc/bashrc
[python@localhost ~]$ su root
密码:
2 - /etc/profile.d/2.sh
3 - /etc/bashrc
5 - ~/.bashrc
[root@localhost /home/python]# exit
exit
登录查看效果
切换标准root用户
[python@localhost ~]$ su - root
密码:
上一次登录:日 6月 12 12:41:11 CST 2022pts/2 上
2 - /etc/profile.d/2.sh
1 - /etc/profile
3 - /etc/bashrc
5 - ~/.bashrc
4 - ~/.bash_profile新建终端效果
Last login: Sun Jun 12 12:35:59 2022 from 10.0.0.1
2 - /etc/profile.d/2.sh
1 - /etc/profile
3 - /etc/bashrc
5 - ~/.bashrc
4 - ~/.bash_profile
[root@localhost ~]#
清理环境
将刚才创建的5条命令执行反向操作
[root@localhost ~]# vim ...退出当前shell环境
[root@localhost ~]# exit
登出
Session stopped- Press <return> to exit tab- Press R to restart session- Press S to save terminal output to file
小结
2.1.2 子shell基础
学习目标
这一节,我们从 基础知识、简单实践、小结 三个方面来学习。
基础知识
场景
之前我们对于环境变量在多个shell环境中的应用进行了学习,那种操作量比较大。对于一些临时性的场景,我们在临时性的环境中,做一些操作,但是不希望对外部的环境造成影响,这个时候我们就涉及到了一些临时shell环境的实践。关于临时shell环境的创建,我们可以借助于()方法来实现。
临时shell
临时shell环境 - 启动子shell(命令列表),在子shell中执行命令列表,退出子shell后,不影响后续环境操作。
临时shell环境 - 不启动子shell{命令列表}, 在当前shell中运行命令列表,会影响当前shell环境的后续操作。
简单实践
() 实践
查看当前shell的pid
[root@localhost ~]# echo $BASHPID
11413
[root@localhost ~]# ps aux | grep bash
root 11413 0.0 0.0 116724 3160 pts/0 Ss 12:54 0:00 -bash
root 11660 0.0 0.0 112824 984 pts/0 R+ 14:49 0:00 grep --color=auto bash查看子shell的pid
[root@localhost ~]# (echo $BASHPID; echo haha)
11661
haha
[root@localhost ~]# (echo $BASHPID; sleep 30)
11711另开一个终端查看效果
[root@localhost ~]# pstree | grep sleep|-sshd-+-sshd---bash---bash---sleep
结果显示:在一个shell内部开启了另一个shell
子shell的操作不影响当前shell环境
[root@localhost ~]# (export SUBSHELL=subshell)
[root@localhost ~]# echo $SUBSHELL[root@localhost ~]#子shell中,查看命令执行效果
[root@localhost ~]# (cd /tmp;pwd)
/tmp
[root@localhost ~]# pwd
/root
{} 实践
查看当前shell的进程id号
[root@localhost ~]# echo $BASHPID
11676在{}环境中查看当前shell的进程id号
[root@localhost ~]# { echo $BASHPID; }
11676
{} 环境中,操作命令会影响当前的shell环境
[root@localhost ~]# { export SUBSHELL=subshell; }
[root@localhost ~]# echo $SUBSHELL
subshell子shell中,查看命令执行效果
[root@localhost ~]# { cd /tmp;pwd; }
/tmp
[root@localhost /tmp]# pwd
/tmp
小结
2.1.3 子shell实践
学习目标
这一节,我们从 CA创建、脚本实践、小结 三个方面来学习。
CA创建
umask基础
umask 解读umask指的是文件权限默认的掩码,默认的值是022,也就是说默认创建的目录是777-022=755默认创建的文件是666-022-544
[root@localhost /data/scripts]# umask
0022
[root@localhost /data/scripts]# mkdir dir
[root@localhost /data/scripts]# touch file
[root@localhost /data/scripts]# ll
总用量 0
drwxr-xr-x 2 root root 6 6月 12 15:18 dir
-rw-r--r-- 1 root root 0 6月 12 15:18 file
CA手工实践
创建临时目录
[root@localhost ~]# mkdir /tmp/CA; cd /tmp/CA生成私钥
[root@localhost /tmp/CA]# (umask 077;openssl genrsa -out ca.key 2048)
Generating RSA private key, 2048 bit long modulus
.............................................................+++
..................+++
e is 65537 (0x10001)
[root@localhost /tmp/CA]# ll
总用量 4
-rw------- 1 root root 1679 6月 12 15:35 ca.key生成证书
[root@localhost /tmp/CA]# openssl req -new -x509 -key ca.key -out ca.crt -days 3650
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:BJ
Locality Name (eg, city) [Default City]:BJ
Organization Name (eg, company) [Default Company Ltd]:BJ
Organizational Unit Name (eg, section) []:BJ
Common Name (eg, your name or your server's hostname) []:www.example.com
Email Address []:bj.example.com
查看生成的文件
[root@localhost /tmp/CA]# ls
ca.crt ca.key查看证书信息
[root@localhost /tmp/CA]# openssl x509 -in ca.crt -noout -text
Certificate:Data:Version: 3 (0x2)Serial Number:d6:25:a6:0e:be:98:ec:48Signature Algorithm: sha256WithRSAEncryptionIssuer: C=CN, ST=BJ, L=BJ, O=BJ, OU=BJ, CN=www.example.com/emailAddress=bj.example.com
脚本实践
创建脚本
查看脚本定制内容
[root@localhost /data/scripts]# cat ca_create.sh
#!/bin/bash
# 功能: 创建自建CA
# 版本:v0.1
# 作者:书记
# 联系:www.superopsmsb.com# 定制普通环境变量
CA_DIR="tls"
CA_DOMAIN="$1"
CA_KEY='tls.key'
CA_CRT='tls.crt'# 创建CA证书
mkdir ${CA_DIR}
(umask 077; cd ${CA_DIR}; openssl genrsa -out tls.key 2048)
openssl req -new -x509 -key ${CA_DIR}/${CA_KEY} -out ${CA_DIR}/${CA_CRT} -subj "/CN=${CA_DOMAIN}" -days 365
执行脚本
[root@localhost /data/scripts]# /bin/bash ca_create.sh www.example.com
Generating RSA private key, 2048 bit long modulus
....+++
.......................................+++
e is 65537 (0x10001)
[root@localhost /data/scripts]# ls tls/
tls.crt tls.key确认效果
[root@localhost /data/scripts]# openssl x509 -in tls/tls.crt -noout -text
Certificate:Data:Version: 3 (0x2)Serial Number:e1:8b:55:da:65:04:fc:c7Signature Algorithm: sha256WithRSAEncryptionIssuer: CN=www.example.com
小结
2.2 脚本外交互
2.2.1 read基础
学习目标
这一节,我们从 基础知识、简单实践、小结 三个方面来学习。
基础知识
场景需求
虽然我们可以通过脚本传参的方式实现脚本一定程度的灵活性,但是生产工作中,有很多更加灵活的场景,需要我们在脚本运行的过程中,传递一些用户定制的具体信息。这个时候,普通的脚本参数就无法满足需求了。read 命令可以实现我们脚本内外的信息自由传递功能。
命令简介
read命令是用于从终端或者文件中读取输入的内建命令,read命令读取整行输入,每行末尾的换行符不被读入。在read命令后面,如果没有指定变量名,读取的数据将被自动赋值给特定的变量REPLY。常用方式如下:
read 从标准输入读取一行并赋值给特定变量REPLY。read answer 从标准输入读取输入并赋值给变量answer。read first last 从标准输入读取内容,将第一个单词放到first中,其他内容放在last中。read -s passwd 从标准输入读取内容,写入passwd,不输入效果read -n n name 从标准输入读取内容,截取n个字符,写入name,超过n个字符,直接退出read -p "prompt" 打印提示,等待输入,并将输入存储在REPLY中。read -r line 允许输入包含反斜杠。read -t second 指定超时时间,默认是秒,整数read -d sper 指定输入信息的截止符号
简单实践
命令操作
交互式接收用户信息
[root@localhost ~]# read
nihao-answer接收用户输入给一个临时变量
[root@localhost ~]# read answer
nihao-answer
[root@localhost ~]# echo $answer
nihao-answer接收多个信息,按照顺序交给不同的临时变量
[root@localhost ~]# read first last
first-1 last-2 end-3
[root@localhost ~]# echo $first
first-1
[root@localhost ~]# echo $last
last-2 end-3
实践2-静默显示
显式接收用户输入信息
[root@localhost ~]# read password
123456
[root@localhost ~]# echo $password
123456隐式接收用户输入信息
[root@localhost ~]# read -s password
[root@localhost ~]# echo $password
abcdefg
实践3-提示用户输入信息
通过 -p 参数提示用户输入的信心
[root@localhost ~]# read -p "请输入登录用户名: " user
请输入登录用户名: root
[root@localhost ~]# echo $user
root
实践4-限制用户输入信息
[root@localhost ~]# read -n 6 -p "sss: " aaa
sss: 123456[root@localhost ~]# read -n 6 -p "只接收6个字符,超过自动退出: " string
只接收6个字符,超过自动退出: 123456[root@localhost ~]#
[root@localhost ~]# echo $string
123456
注意:-p + -s 的组合会导致不会自动换行,可以结合 echo的方式实现换行
实践5-等待时长
[root@localhost ~]# read -t 5 -p "等待5秒后自动退出! " second
等待5秒后自动退出! 4
[root@localhost ~]# echo $second
4
[root@localhost ~]# read -t 5 -p "等待5秒后自动退出! " second
等待5秒后自动退出! [root@localhost ~]#
小结
2.2.2 案例实践
学习目标
这一节,我们从 登录模拟、堡垒机实践、小结 三个方面来学习。
登录模拟
需求
模拟shell终端工具的登录,功能过程如下:请输入用户名: 请输入密码:您输入的用户名和密码是: xxx
脚本实践
[root@localhost ~]# cat simple_login.sh
#!/bin/bash
# 功能: 模拟shell登录
# 版本:v0.1
# 作者:书记
# 联系:www.superopsmsb.com# 定制命令变量
OS_INFO=$(cat /etc/redhat-release)
KERNEL_INFO=$(uname -r)
OS_ARCH=$(uname -m)
HOSTNAME=$(hostname)# 清屏
clear# 输出提示信息
echo -e "\e[32m${OS_INFO} \e[0m"
echo -e "\e[32mKernel ${KERNEL_INFO} on an ${OS_ARCH} \e[0m"
echo "---------------------------------"
# 交互输入登陆信息
read -p "请输入用户名:" account
read -s -t30 -p "请输入登录密码:" password
echo
echo "---------------------------------"
# 输出用户输入信息
printf "您输入的用户名:\e[31m%s\e[0m您输入的密码:\e[31m%s\e[0m\n" ${account} ${password}
脚本执行效果
[root@10 ~]# /bin/bash simple_login.sh
CentOS Linux release 7.9.2009 (Core)
Kernel 3.10.0-1160.el7.x86_64 on an x86_64
---------------------------------
请输入用户名:root
请输入登录密码:
---------------------------------
您输入的用户名:root您输入的密码:123456
堡垒机实践
功能需求
模拟堡垒机的登录,功能过程如下:请选择要登录的主机请输入用户名: 使用指定的用户连接远程主机
脚本实践
[root@localhost ~]# cat simple_jumpserver.sh
#!/bin/bash
# 功能:定制堡垒机的展示页面
# 版本:v0.2
# 作者:书记
# 联系:www.superopsmsb.com# 堡垒机的信息提示
echo -e "\e[31m \t\t 欢迎使用堡垒机"echo -e "\e[32m
-----------请选择你要登录的远程主机-----------1: 10.0.0.14 (nginx)2: 10.0.0.15 (tomcat)3: 10.0.0.19 (apache)q: 使用本地主机
----------------------------------------------
"'\033[0m'# 由于暂时没有学习条件判断,所以暂时选择 q
read -p "请输入您要选择的远程主机编号: " host_index
read -p "请输入登录本地主机的用户名: " user# 远程连接主机
ssh $user@localhost
脚本执行效果
[root@10 ~]# /bin/bash simple_jumpserver.sh欢迎使用堡垒机-----------请选择你要登录的远程主机-----------1: 10.0.0.14 (nginx)2: 10.0.0.15 (tomcat)3: 10.0.0.19 (apache)q: 使用本地主机
----------------------------------------------请输入您要选择的远程主机编号: p
请输入登录本地主机的用户名: root
The authenticity of host 'localhost (::1)' can't be established.
ECDSA key fingerprint is SHA256:XUJsgk4cTORxdcswxIKBGFgrrqFQzpHmKnRRV6ABMk4.
ECDSA key fingerprint is MD5:71:74:46:50:3f:40:4e:af:ad:d3:0c:de:2c:fc:30:c0.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'localhost' (ECDSA) to the list of known hosts.
root@localhost's password:
Last login: Mon Jun 13 12:19:34 2022 from 10.0.0.1
[root@10 ~]# exit
登出
小结
3 表达式
3.1 运算符
3.1.1 运算符基础
学习目标
这一节,我们从 基础知识、赋值运算、小结 三个方面来学习。
基础知识
需求
根据我们之前的学习,通过现有的知识内容可以完成一个简单的功能操作,即使通过所谓的脚本参数可以实现一个脚本在多个数据值的情况下实现不同的结果。但是问题是,目前脚本本身还没有实现灵活的机制。所谓脚本级别的灵活机制,说的是脚本内部能够实现数据的操作和判断。而数据的操作也是判断过程中必须的一个条件组成部分。所以数据的操作是脚本的一个核心内容。
数据操作
关于shell可以实施的数据操作,按照不同的业务场景主要可以分为如下两个方面:运算符 - 数据值之间的操作赋值运算- 结果值输出- 示例: =、*=、/=、%=、+=、-=、<<=、>>=、&=、^=、|=等二元运算 - 数据值操作- 示例: +、-、*、/、%等高阶运算- 更高一级的数学运算- 示例:**、^、++、--、其他运算 - 其他运算操作- 示例:<<、>>等
注意:这些所谓的运算符一般很难单独来使用,都需要结合计算表达式来实现相应的效果
表达式 - 数据值在特定场景的运算符操作计算表达式- 将多个值的运算操作执行起来- 示例:bc、let、expr、$(())等测试表达式 - 判断结果值是否满足需求- 示例:test、[]等逻辑表达式 - 多条件的多场景组合- 示例:&&、||、and、or、not、&、|等比较表达式 - 判断数据之间的适配关系- 示例:-f|d|s、-r|x|w、-e、-n、==、!=、>、<、<=、>=等三元表达式- 多逻辑的简单计算表达式- 示例:expr?expr:expr集合表达式 - 表达式之间的关联关系- 示例:expr1 , expr2、 [[ ]]、[ -a|o ]、[ ! ]等
赋值运算
基础知识
所谓的赋值运算,其实指的就是将一个值赋予一个变量名,虽然我们在变量一节中对于该知识点进行了一些基础性的操作,但是赋值运算仍然还有一些其他的表现样式,尤其是关于命令计算相关的。
简单的赋值操作
为变量赋值
[root@localhost ~]# echo $num $string[root@localhost ~]# num=123 string=abc
[root@localhost ~]# echo $num $string
123 abc
赋值时候定制属性
[root@localhost ~]# declare stringnum=123
[root@localhost ~]# declare string=nihao
[root@localhost ~]# echo $stringnum $string
123 nihao
[root@localhost ~]# declare -i num=654
[root@localhost ~]# declare -i num2=aaa
[root@localhost ~]# echo $num $num2
654 0
获取特定数据
[root@localhost ~]# myuser=$(whoami)
[root@localhost ~]# echo $myuser
root
[root@localhost ~]# kernel_info=$(cat /etc/redhat-release)
[root@localhost ~]# echo $kernel_info
CentOS Linux release 7.9.2009 (Core)
小结
3.1.2 简单计算
学习目标
这一节,我们从 [ ] 、 l e t 、 ( ( ) ) 、 []、let、(())、 []、let、(())、(())、小结 五个方面来学习。
$[]
简介
$[]方法,常用于整数计算场景,适合不太复杂的计算,运算结果是小数的也会自动取整。后面的几种也是一样
格式
方法1:$[计算表达式]
方法2:a=$[变量名a+1]注意:这里的表达式可以不是一个整体
简单示例
简单运算
[root@localhost ~]# echo $[100/5]
20
[root@localhost ~]# echo $[ 2 + 5 ]
7变量参与运算
[root@localhost ~]# a=6
[root@localhost ~]# a=$[a+1]
[root@localhost ~]# echo $a
7运算结果取整
[root@localhost ~]# echo $[100/3]
33
let
简介
let是另外一种相对来说比较简单的数学运算符号了
格式
let 变量名a=变量名a+1注意:表达式必须是一个整体,中间不能出现空格等特殊字符
简单示例
简单运算
[root@localhost ~]# i=1
[root@localhost ~]# let i=i+7
[root@localhost ~]# echo $i
8let表达式必须是一个整体
[root@localhost ~]# let i = i * 2
bash: let: =: 语法错误: 期待操作数 (错误符号是 "=")
[root@localhost ~]# let i=i * 2
bash: let: anaconda-ks.cfg: 语法错误: 无效的算术运算符 (错误符号是 ".cfg")
[root@localhost ~]# let i=i*2
[root@localhost ~]# echo $i
16
(())
简介
(())的操作与let基本一致,相当于let替换成了 (())
格式
((变量计算表达式))
注意:对于 $(())中间的表达式,可以不是一个整体,不受空格的限制
简单实践
[root@localhost ~]# num1=34
[root@localhost ~]# ((num2=num1+34))
[root@localhost ~]# echo $num2
68
$(())
简介
$(())的操作,相当于 (()) + echo $变量名 的组合
格式
echo $((变量计算表达式))
注意:对于 $(())中间的表达式,可以不是一个整体,不受空格的限制
简单实践
[root@localhost ~]# num1=34
[root@localhost ~]# echo $((num2=num1+34))
68
小结
3.1.3 赋值运算进阶
学习目标
这一节,我们从 二元运算、赋值运算、小结、三个方面来学习。
二元运算
简介
所谓的二元运算,指的是 多个数字进行+-*/%等运算
简单实践
加法运算
[root@localhost ~]# echo $(( 4 + 4 ))
8
[root@localhost ~]# num1=3 num2=4
[root@localhost ~]# echo $(($num1 + $num2))
7减法运算
[root@localhost ~]# echo $((8-2))
6
[root@localhost ~]# echo $(($num2-$num1))
1乘法运算
[root@localhost ~]# echo $((8*2))
16
[root@localhost ~]# echo $(($num2*$num1))
12除法运算
[root@localhost ~]# echo $((8/2))
4
[root@localhost ~]# echo $(($num2/$num1))
1取余运算
[root@localhost ~]# echo $((8%3))
2
[root@localhost ~]# echo $(($num2%$num1))
1
案例实践-小学计算题
案例需求:鸡兔同笼,共有30个头,88只脚。求笼中鸡兔各有多少只?
查看脚本内容
[root@localhost ~]# cat count_head_feet.sh
#!/bin/bash
# 功能:小学计算题目
# 版本:v0.1
# 作者:书记
# 联系:www.superopsmsb.com# 定制普通变量
head="$1"
feet="$2"# 计算逻辑
# 每个头至少两只脚,多出的脚都是兔子的
rabbit_num=$(( ($feet - $head - $head) / 2))
chick_num=$[ $head - $rabbit_num ]# 结果输出
echo -e "\e[31m\t鸡和兔的数量\e[0m"
echo -e "\e[32m============================"
echo "鸡的数量: ${chick_num}"
echo "兔的数量:${rabbit_num}"
echo -e "============================\e[0m"
脚本执行效果
[root@localhost ~]# /bin/bash count_head_feet.sh 30 88鸡和兔的数量
============================
鸡的数量: 16
兔的数量:14
============================
赋值运算
简介
这里的赋值运算,是一种进阶版本的复制操作,常见的样式如下:样式1:+=、-=、*=、/=- 在自身的基础上进行二元运算,结果值还是自己样式2:++、--- 在自身的基础上进行递增和递减操作,结果值还是自己
简单实践
+=运算
[root@localhost ~]# num1=6
[root@localhost ~]# let value+=$num1 # 相当于 let value=value+$num1
[root@localhost ~]# echo $value
6-=运算
[root@localhost ~]# let value-=2 # 相当于 let value=value-2
[root@localhost ~]# echo $value
4*=运算
[root@localhost ~]# let value*=2 # 相当于 let value=value*2
[root@localhost ~]# echo $value
8/=运算
[root@localhost ~]# let value/=2 # 相当于 let value=value/2
[root@localhost ~]# echo $value
4
i++运算
[root@localhost ~]# value=9
[root@localhost ~]# let value++ # 相当于 let value=value+1
[root@localhost ~]# echo $value
10
[root@localhost ~]# let value++ # 相当于 let value=value+1
[root@localhost ~]# echo $value
11++i运算
[root@localhost ~]# let ++value # 相当于 let value=value+1
[root@localhost ~]# echo $value
12
--运算
[root@localhost ~]# value=9
[root@localhost ~]# let value-- # 相当于 let value=value-1
[root@localhost ~]# echo $value
8
[root@localhost ~]# let value-- # 相当于 let value=value-1
[root@localhost ~]# echo $value
7
[root@localhost ~]# let --value # 相当于 let value=value-1
[root@localhost ~]# echo $value
6
小结
3.1.4 expr计算
学习目标
这一节,我们从 基础知识、简单实践、小结 三个方面来学习。
基础知识
简介
expr即可以做常见的整数运算,还可以做数字比较,字符串计算等操作。
格式
数字场景:expr 运算表达式
字符串场景:match:用户获取匹配到字符串的长度expr match 字符串 匹配内容substr:截取字符串expr substr 字符串 起始位置 截取长度注意:起始位置值>=1index:查找第一次匹配字符的位置expr index 字符串 字符length:计算字符串的长度expr length 字符串
简单实践
数学运算
数学运算
[root@localhost ~]# expr 1 + 2 - 3 \* 4 / 5 + \( 6 - 7 \) \* 8
-7
[root@localhost ~]# x=1
[root@localhost ~]# expr $x + 4
5
字符串运算
用户获取匹配到字符串的长度
[root@localhost ~]# file=jdslkfajkldsjafklds
[root@localhost ~]# expr match $file "k.*j"
0
[root@localhost ~]# expr match $file ".*j"
13截取字符串
[root@localhost ~]# expr substr $file 0 4
[root@localhost ~]# expr substr $file 1 4
jdsl查找第一次匹配字符的位置
[root@localhost ~]# expr index $file b
0
[root@localhost ~]# expr index $file j
1计算字符串的长度
[root@localhost ~]# expr length $file
19
小结
3.1.5 bc计算
学习目标
这一节,我们从 基础知识、简单实践、小结 三个方面来学习。
基础知识
简介
bc是一种任意精度的计算语言,提供了语法结构,比如条件判断、循环等,功能是很强大的,还能进行进制转换。
常见参数-i 强制交互模式;-l 使用bc的内置库,bc里有一些数学库,对三角计算等非常实用;-q 进入bc交互模式时不再输出版本等多余的信息。
特殊变量ibase,obase 用于进制转换,ibase是输入的进制,obase是输出的进制,默认是十进制;scale 小数保留位数,默认保留0位。
简单实践
实践1-交互示例
在shell命令行直接输入bc即进入bc语言的交互模式
[root@localhost ~]# bc -l -q
4 / 3
1.33333333333333333333
3 + 4
7
5 * 8
40
exit
0
^C
(interrupt) Exiting bc.
[root@localhost ~]#
实践2 - 非交互示例
格式:echo "属性设置; 计算表达式" | bc
[root@localhost ~]# echo "scale=2; 9-8*2/5^2" | bc
8.36
[root@localhost ~]# echo "scale=2; sqrt(10)" | bc
3.16
[root@localhost ~]# echo '45.36-22.33' | bc
23.03
实践3 - 内存使用率统计
查看脚本效果
[root@localhost ~]# cat memory_info.sh
#!/bin/bash
# 功能:定制内存信息的使用率
# 版本:v0.1
# 作者:书记
# 联系:www.superopsmsb.com# 定制基础信息
temp_file='/tmp/free.txt'
hostname=$(hostname)# 获取内存信息
free -m > /tmp/free.txt
# 获得内存总量
memory_totle=$(grep -i "mem" /tmp/free.txt | tr -s " " | cut -d " " -f2)
# 获得内存使用的量
memory_use=$(grep -i "mem" /tmp/free.txt | tr -s " " | cut -d " " -f3)
# 获得内存空闲的量
memory_free=$(grep -i "mem" /tmp/free.txt | tr -s " " | cut -d " " -f4)# 定制使用比例
# 获取内存使用率
percentage_use=$(echo "scale=2; $memory_use * 100 / $memory_totle" | bc)
# 定制内存空闲率
percentage_free=$(echo "scale=2; $memory_free * 100 / $memory_totle" | bc)# 内容信息输出
echo -e "\e[31m\t${hostname} 内存使用信息统计\e[0m"
echo -e "\e[32m=========================================="
echo '内存总量: ' ${memory_totle}
echo '内存使用量: ' ${memory_use}
echo '内存空闲量: ' ${memory_free}
echo '内存使用比率: ' ${percentage_use}
echo '内存空闲利率: ' ${percentage_free}
echo "=========================================="
echo -e "\e[0m"
脚本执行后效果
[root@localhost ~]# /bin/bash memory_info.shlocalhost 内存使用信息统计
==========================================
内存总量: 3770
内存使用量: 238
内存空闲量: 3376
内存使用比率: 6.31
内存空闲利率: 89.54
==========================================
小结
3.2 表达式
3.2.1 基础知识
学习目标
这一节,我们从 基础知识、测试表达式、小结 三个方面来学习。
基础知识
简介
所谓的表达式,就是在场景需求的前提下,判断数据和运算符的操作是否满足需求。
语法格式:
格式真实值 操作符 真实值 比较运算符 预期值
示例3 + 4 > 6
要点:表达式应该具有判断的功能
测试表达式
简介
Shell环境根据命令执行后的返回状态值($?)来判断是否执行成功,当返回值为0,表示成功,值为其他时,表示失败。使用专门的测试工具---test命令,可以对特定条件进行测试,并根据返回值来判断条件是否成立(返回值0为成立)
测试表达式
样式1: test 条件表达式
样式2: [ 条件表达式 ]
注意:以上两种方法的作用完全一样,后者为常用。但后者需要注意方括号[、]与条件表达式之间至少有一个空格。test跟 [] 的意思一样条件成立,状态返回值是0条件不成立,状态返回值是1
简单示例
test语法示例
[root@localhost ~]# test 1 == 1
[root@localhost ~]# echo $?
0
[root@localhost ~]# test 1 == 2
[root@localhost ~]# echo $?
1test -v语法测试变量有没有被设置值,亦可理解为变量是否为空。
[root@localhost ~]# echo $empty[root@localhost ~]# test -v empty
[root@localhost ~]# echo $?
1
[root@localhost ~]# empty=value
[root@localhost ~]# echo $?
0
[] 语法示例
[root@localhost ~]# [ 1 == 1 ]
[root@localhost ~]# echo $?
0
[root@localhost ~]# [ 1 == 12 ]
[root@localhost ~]# echo $?
1
[] 格式解读
[root@localhost ~]# [ 1 == 12]
bash: [: 缺少 `]'
[root@localhost ~]# [ 1 == 12] ]
[root@localhost ~]# echo $?
1
小结
3.2.2 逻辑表达式
学习目标
这一节,我们从 基础知识、简单实践、小结 三个方面来学习。
基础知识
简介
逻辑表达式一般用于判断多个条件之间的依赖关系。常见的逻辑表达式有:&& 和 ||,根据观察的角度不同含义也不同
语法解读
&& 示例:命令1 && 命令2如果命令1执行成功,那么我才执行命令2 -- 夫唱妇随如果命令1执行失败,那么命令2也不执行
|| 示例:命令1 || 命令2如果命令1执行成功,那么命令2不执行 -- 对着干如果命令1执行失败,那么命令2执行
!示例:! 命令如果命令执行成功,则整体取反状态
组合使用
使用样式:命令1 && 命令2 || 命令3 方便理解的样式 ( 命令1 && 命令2 ) || 命令3
功能解读:命令1执行成功的情况下,执行命令2命令2执行失败的情况下,执行命令3
注意:&& 必须放到前面,|| 放到后面
简单实践
实践1-语法实践
&& 语法实践
[root@localhost ~]# [ 1 = 1 ] && echo "条件成立"
条件成立
[root@localhost ~]# [ 1 = 2 ] && echo "条件成立"|| 语法实践
[root@localhost ~]# [ 1 = 2 ] || echo "条件不成立"
条件不成立
[root@localhost ~]# [ 1 = 1 ] || echo "条件不成立"
[root@localhost ~]#
实践2-案例实践
执行文件前保证具备执行权限
[root@localhost ~]# cat test_argnum.sh
#!/bin/bash
# && 和 || 演示# 设定普通变量
arg_num=$#[ $# == 1 ] && echo "脚本参数为1,允许执行脚本"
[ $# == 1 ] || echo "脚本参数不为1,不允许执行脚本"
脚本执行后效果
[root@localhost ~]# /bin/bash test_argnum.sh
脚本参数不为1,不允许执行脚本
[root@localhost ~]# /bin/bash test_argnum.sh 1
脚本参数为1,允许执行脚本
[root@localhost ~]# /bin/bash test_argnum.sh 1 2
脚本参数不为1,不允许执行脚本
实践3-取反
查看正常的字符串判断
[root@localhost ~]# [ aaa == aaa ]
[root@localhost ~]# echo $?
0查看取反的效果判断
[root@localhost ~]# [ ! aaa == aaa ]
[root@localhost ~]# echo $?
1
[root@localhost ~]# [ ! aaa == bbb ]
[root@localhost ~]# echo $?
0
实践4 - 组合使用
[root@localhost ~]# [ -d /etc ] && echo "目录存在" || echo "目录不存在"
目录存在
[root@localhost ~]# [ -d /etc1 ] && echo "目录存在" || echo "目录不存在"
目录不存在
实践5 - 主机网络连通性测试
查看脚本内容
[root@localhost ~]# cat host_network_test.sh
#!/bin/bash
# 功能:测试主机网络连通性
# 版本:v0.1
# 作者:书记
# 联系:www.superopsmsb.com# 定制普通变量
host_addr="$1"# 脚本基本判断
[ -z ${host_addr} ] && echo "请输入待测试主机ip" && exit
[ $# -ne 1 ] && echo "请保证输入1个脚本参数" && exit# 测试主机网络
net_status=$(ping -c1 -w1 ${host_addr} >/dev/null 2>&1 && echo "正常" || echo "异常")# 信息输出
echo -e "\e[31m\t主机网络状态信息\e[0m"
echo -e "\e[32m================================"
echo "${host_addr} 网络状态: ${net_status}"
echo -e "================================\e[0m"
脚本执行效果
[root@localhost ~]# /bin/bash host_network_test.sh
请输入待测试主机ip
[root@localhost ~]# /bin/bash host_network_test.sh aa bb
请保证输入1个脚本参数
[root@localhost ~]# /bin/bash host_network_test.sh 10.0.0.12主机网络状态信息
================================
10.0.0.12 网络状态: 正常
================================
[root@localhost ~]# /bin/bash host_network_test.sh 10.0.0.15主机网络状态信息
================================
10.0.0.15 网络状态: 异常
================================
小结
3.2.3 字符串表达式
学习目标
这一节,我们从 基础知识、简单实践、小结 三个方面来学习。
基础知识
简介
所谓的字符串表达式,主要是判断 比较运算符 两侧的值的内容是否一致,由于bash属于弱类型语言,所以,默认情况下,无论数字和字符,都会可以被当成字符串进行判断。
符号解读
内容比较判断str1 == str2 str1和str2字符串内容一致str1 != str2 str1和str2字符串内容不一致,!表示相反的意思内容空值判断-z str 空值判断,获取字符串长度,长度为0,返回True-n "str" 非空值判断,获取字符串长度,长度不为0,返回True注意:str外侧必须携带"",否则无法判断
简单实践
实践1-内容比较判断
判断字符串内容是否一致
[root@localhost ~]# test aaa == bbb
[root@localhost ~]# echo $?
1
[root@localhost ~]# test aaa != bbb
[root@localhost ~]# echo $?
0判断数字内容是否一致
[root@localhost ~]# num1=234 num2=456
[root@localhost ~]# test $num1 == $num2
[root@localhost ~]# echo $?
1
[root@localhost ~]# test $num1 != $num2
[root@localhost ~]# echo $?
0
实践2-空值判断
判断内容是否为空
[root@localhost ~]# string=nihao
[root@localhost ~]# test -z $string
[root@localhost ~]# echo $?
1
[root@localhost ~]# test -z $string1
[root@localhost ~]# echo $?
0判断内容是否为不空,可以理解为变量是否被设置
[root@localhost ~]# unset str
[root@localhost ~]# [ -n $str ]
[root@localhost ~]# echo $?
0
[root@localhost ~]# [ -n "$str" ]
[root@localhost ~]# echo $?
1
[root@localhost ~]# str=value
[root@localhost ~]# [ -n "$str" ]
[root@localhost ~]# echo $?
0
实践3-脚本实践
查看脚本内容
[root@localhost ~]# cat simple_login_string.sh
#!/bin/bash
# 功能: 模拟shell登录
# 版本:v0.1
# 作者:书记
# 联系:www.superopsmsb.com# 定制命令变量
OS_INFO=$(cat /etc/redhat-release)
KERNEL_INFO=$(uname -r)
OS_ARCH=$(uname -m)
HOSTNAME=$(hostname)# 清屏
clear# 输出提示信息
echo -e "\e[32m${OS_INFO} \e[0m"
echo -e "\e[32mKernel ${KERNEL_INFO} on an ${OS_ARCH} \e[0m"
echo "---------------------------------"
# 交互输入登陆信息
read -p "请输入用户名:" account
[ -z $account ] && read -p "请输入用户名:" account
read -s -t30 -p "请输入登录密码:" password
echo
echo "---------------------------------"
# 输出用户输入信息
[ $account == 'root' ] && [ $password == '123456' ] && echo "登录成功" || echo "登录失败"
脚本执行测试
[root@localhost ~]# /bin/bash simple_login_string.sh
CentOS Linux release 7.9.2009 (Core)
Kernel 3.10.0-1160.el7.x86_64 on an x86_64
---------------------------------
请输入用户名:root
请输入登录密码:
---------------------------------
登录成功
[root@localhost ~]# /bin/bash simple_login_string.sh
CentOS Linux release 7.9.2009 (Core)
Kernel 3.10.0-1160.el7.x86_64 on an x86_64
---------------------------------
请输入用户名:
请输入用户名:root1
请输入登录密码:
---------------------------------
登录失败
[root@localhost ~]#
小结
3.2.4 文件表达式
学习目标
这一节,我们从 基础知识、简单实践、小结 三个方面来学习。
基础知识
简介
所谓的文件表达式,主要是判断文件相关的权限和属性信息的。
表达式解读
文件属性判断-d 检查文件是否存在且为目录文件-f 检查文件是否存在且为普通文件-S 检查文件是否存在且为socket文件-L 检查文件是否存在且为链接文件-O 检查文件是否存在并且被当前用户拥有-G 检查文件是否存在并且默认组为当前用户组文件权限判断 -r 检查文件是否存在且可读-w 检查文件是否存在且可写-x 检查文件是否存在且可执行文件存在判断-e 检查文件是否存在-s 检查文件是否存在且不为空文件新旧判断file1 -nt file2 检查file1是否比file2新file1 -ot file2 检查file1是否比file2旧file1 -ef file2 检查file1是否与file2是同一个文件,判定依据的是i节点
简单实践
实践1- 文件属性判断
[root@localhost ~]# [ -f weizhi.sh ] && echo "是一个文件"
[root@localhost ~]# [ -f weizhi.sddh ] || echo "不是一个文件"
不是一个文件
[root@localhost ~]# [ -d weizhi.sddh ] || echo "不是一个目录"
不是一个目录
[root@localhost ~]# [ -d /tmp ] && echo "是一个目录"
是一个目录
实践2-文件权限判断
[root@localhost ~]# [ -x memory_info.sh ] || echo "文件没有执行权限"
文件没有执行权限
[root@localhost ~]# [ -x memory_info.sh ] || chmod +x memory_info.sh
[root@localhost ~]# [ -x memory_info.sh ] && ./memory_info.shlocalhost 内存使用信息统计
==========================================
内存总量: 3770
内存使用量: 242
内存空闲量: 3372
内存使用比率: 6.41
内存空闲利率: 89.44
==========================================
实践3-文件存在判断
文件内容空值判断
[root@localhost ~]# touch nihao.txt
[root@localhost ~]# [ -s nihao.txt ] || echo "文件为空"
文件为空
[root@localhost ~]# echo nihao > file.txt
[root@localhost ~]# [ -s file.txt ] && echo "文件不为空"
文件不为空
文件存在与否判断
[root@localhost ~]# [ -e file.txt ] && echo "文件存在"
文件存在
[root@localhost ~]# [ -e file.txt1 ] || echo "文件不存在"
文件不存在
小结
3.2.5 数字表达式
学习目标
这一节,我们从 基础知识、简单实践、小结 三个方面来学习。
基础知识
简介
主要根据给定的两个值,判断第一个与第二个数的关系,如是否大于、小于、等于第二个数。
语法解读
n1 -eq n2 相等 n1 -ne n2 不等于 n1 -ge n2 大于等于 n1 -gt n2 大于 n1 -lt n2 小于 n1 -le n2 小于等于
简单实践
实践1-命令实践
[root@localhost ~]# [ 3 -gt 2 ] && echo "3 大于 2"
3 大于 2
[root@localhost ~]# [ 3 -ne 2 ] && echo "3 不等于 2"
3 不等于 2
[root@localhost ~]# [ 3 -eq 3 ] && echo "3 等于 3"
3 等于 3
实践2-脚本安全
查看脚本内容
[root@localhost ~]# cat test_argnum.sh
#!/bin/bash
# -eq 和 -ne 演示# 设定普通变量
arg_num=$#[ $arg_num -eq 1 ] && echo "脚本参数为1,允许执行脚本"
[ $arg_num -ne 1 ] && echo "脚本参数不为1,不允许执行脚本"
脚本执行效果
root@localhost ~]# /bin/bash test_argnum.sh
脚本参数不为1,不允许执行脚本
[root@localhost ~]# /bin/bash test_argnum.sh 1
脚本参数为1,允许执行脚本
[root@localhost ~]# /bin/bash test_argnum.sh 1 2
脚本参数不为1,不允许执行脚本
小结
3.3 表达式进阶
3.3.3 [[]] 测试进阶
学习目标
这一节,我们从 基础知识、简单实践、小结 三个方面来学习。
基础知识
简介
我们之前学习过 test 和 [ ] 测试表达式,这些简单的测试表达式,仅仅支持单条件的测试。如果需要针对多条件测试场景的话,我们就需要学习[[ ]] 测试表达式了。我们可以将 [[ ]] 理解为增强版的 [ ],它不仅仅支持多表达式,还支持扩展正则表达式和通配符。
语法解析
基本格式:[[ 源内容 操作符 匹配内容 ]]操作符解析:== 左侧源内容可以被右侧表达式精确匹配=~ 左侧源内容可以被右侧表达式模糊匹配
简单实践
实践1-内容的基本匹配
定制默认的的变量
[root@localhost ~]# string=value
[root@localhost ~]# echo $string
value
[root@localhost ~]# [[ $string == value ]]
[root@localhost ~]# echo $?
0[[]] 支持通配符
[root@localhost ~]# [[ $string == v* ]]
[root@localhost ~]# echo $?
0使用""取消正则,则内容匹配失败
[root@localhost ~]# [[ $string == v"*" ]]
[root@localhost ~]# echo $?
1使用\取消正则,则内容匹配失败
[root@localhost ~]# [[ $string == v\* ]]
[root@localhost ~]# echo $?
1
实践2-文件的匹配
定制文件名称
[root@localhost ~]# script_name=file.sh
[root@localhost ~]# [[ $script_name == *.sh ]]
[root@localhost ~]# echo $?
0尝试其他匹配
[root@localhost ~]# [[ $script_name == *.txt ]]
[root@localhost ~]# echo $?
1
[root@localhost ~]# [[ $script_name != *.txt ]]
[root@localhost ~]# echo $?
0
小结
3.3.2 集合基础
学习目标
这一节,我们从 基础知识、简单实践、小结 三个方面来学习。
基础知识
简介
所谓的集合,主要是针对多个条件表达式组合后的结果,尤其是针对于逻辑场景的组合。初中数学的相关逻辑示意图:
表现样式
两个条件1 - 真 0 - 假
三种情况:与 - & 或 - | 非 - !注意:这里的 0 和 1 ,千万不要与条件表达式的状态值混淆
与关系:0 与 0 = 0 0 & 0 = 00 与 1 = 0 0 & 1 = 01 与 0 = 0 1 & 0 = 01 与 1 = 1 1 & 1 = 1
或关系:0 或 0 = 0 0 | 0 = 00 或 1 = 1 0 | 1 = 11 或 0 = 1 1 | 0 = 11 或 1 = 1 1 | 1 = 1
非关系:非 1 = 0 ! true = false非 0 = 1 ! false = true
简单实践
实践1- 简单判断
或实践
[root@localhost ~]# echo $[ 0 | 1 ]
1
[root@localhost ~]# echo $[ 0 | 0 ]
0
[root@localhost ~]# echo $[ 1 | 0 ]
1
[root@localhost ~]# echo $[ 1 | 1 ]
1
与实践
[root@localhost ~]# echo $[ 1 & 1 ]
1
[root@localhost ~]# echo $[ 1 & 0 ]
0
[root@localhost ~]# echo $[ 0 & 1 ]
0
[root@localhost ~]# echo $[ 0 & 0 ]
0
非实践
[root@localhost ~]# true
[root@localhost ~]# echo $?
0
[root@localhost ~]# false
[root@localhost ~]# echo $?
1[root@localhost ~]# echo $[ ! 0 ]
1
[root@localhost ~]# echo $[ ! 1 ]
0
小结
3.3.3 逻辑组合
学习目标
这一节,我们从 基础知识、简单实践、小结 三个方面来学习。
基础知识
简介
所谓的条件组合,指的是在同一个场景下的多个条件的综合判断效果。
语法解析
方法1:[ 条件1 -a 条件2 ] - 两个条件都为真,整体为真,否则为假[ 条件1 -o 条件2 ] - 两个条件都为假,整体为假,否则为真
方法2:[[ 条件1 && 条件2 ]] - 两个条件都为真,整体为真,否则为假[[ 条件1 || 条件2 ]] - 两个条件都为假,整体为假,否则为真
简单实践
实践1-[]组合实践
[root@localhost ~]# user=root pass=123456
[root@localhost ~]# [ $user == "root" -a $pass == "123456" ]
[root@localhost ~]# echo $?
0
[root@localhost ~]# [ $user == "root" -a $pass == "1234567" ]
[root@localhost ~]# echo $?
1
[root@localhost ~]# [ $user == "root" -o $pass == "1234567" ]
[root@localhost ~]# echo $?
0
[root@localhost ~]# [ $user == "root1" -o $pass == "1234567" ]
[root@localhost ~]# echo $?
1
实践2 - [[]]组合实践
[root@localhost ~]# [[ $user == "root" && $pass == "123456" ]]
[root@localhost ~]# echo $?
0
[root@localhost ~]# [[ $user == "root" && $pass == "1234567" ]]
[root@localhost ~]# echo $?
1
[root@localhost ~]# [[ $user == "root" || $pass == "1234567" ]]
[root@localhost ~]# echo $?
0
[root@localhost ~]# [[ $user == "root1" || $pass == "1234567" ]]
[root@localhost ~]# echo $?
1
小结
3.3.4 综合实践
学习目标
这一节,我们从 堡垒机登录、信息检测、小结 三个方面来学习。
堡垒机登录
脚本功能-扩充用户名和密码验证功能
[root@localhost ~]# cat simple_jumpserver.sh
#!/bin/bash
# 功能:定制堡垒机的展示页面
# 版本:v0.3
# 作者:书记
# 联系:www.superopsmsb.com# 定制普通变量
login_user='root'
login_pass='123456'# 堡垒机的信息提示
echo -e "\e[31m \t\t 欢迎使用堡垒机"
echo -e "\e[32m
-----------请选择你要登录的远程主机-----------1: 10.0.0.14 (nginx)2: 10.0.0.15 (tomcat)3: 10.0.0.19 (apache)q: 使用本地主机
----------------------------------------------
"'\033[0m'# 由于暂时没有学习条件判断,所以暂时选择 q
read -p "请输入您要选择的远程主机编号: " host_index
read -p "请输入登录本地主机的用户名: " user
read -s -p "请输入登录本地主机的密码: " password
echo
# 远程连接主机
[[ ${user} == ${login_user} && ${password} == ${login_pass} ]] && echo "主机登录验证成功" || echo "您输入的用户名或密码有误"
脚本执行效果
[root@localhost ~]# /bin/bash simple_jumpserver.sh欢迎使用堡垒机-----------请选择你要登录的远程主机-----------1: 10.0.0.14 (nginx)2: 10.0.0.15 (tomcat)3: 10.0.0.19 (apache)q: 使用本地主机
----------------------------------------------请输入您要选择的远程主机编号: q
请输入登录本地主机的用户名: root
请输入登录本地主机的密码:
主机登录验证成功
[root@localhost ~]# /bin/bash simple_jumpserver.sh欢迎使用堡垒机-----------请选择你要登录的远程主机-----------1: 10.0.0.14 (nginx)2: 10.0.0.15 (tomcat)3: 10.0.0.19 (apache)q: 使用本地主机
----------------------------------------------请输入您要选择的远程主机编号: q
请输入登录本地主机的用户名: python
请输入登录本地主机的密码:
您输入的用户名或密码有误
信息检测
脚本功能-检测公司网站的存活
判断网站的命令
[root@localhost ~]# wget --spider -T5 -q -t2 www.baidu.com
[root@localhost ~]# echo $?
0
[root@localhost ~]# wget --spider -T5 -q -t2 www.baidu.com1
[root@localhost ~]# echo $?
4
[root@localhost ~]# curl -s -o /dev/null www.baidu.com
[root@localhost ~]# echo $?
0
[root@localhost ~]# curl -s -o /dev/null www.baidu.com1
[root@localhost ~]# echo $?
6
脚本的核心内容
[root@localhost ~]# cat site_healthcheck.sh
#!/bin/bash
# 功能:定制站点的检测功能
# 版本:v0.1
# 作者:书记
# 联系:www.superopsmsb.com# 定制普通变量
site_addr="$1"
# 脚本基本判断
[ -z ${site_addr} ] && echo "请输入待测试站点域名" && exit
[ $# -ne 1 ] && echo "请保证输入1个脚本参数" && exit# 检测平台的信息提示
echo -e "\e[32m-----------检测平台支持的检测类型-----------1: wget2: curl
----------------------------------------"'\033[0m'# 选择检测类型
read -p "请输入网站的检测方法: " check_type
site_status=$([ ${check_type} == 1 ] && wget --spider -T5 -q -t2 ${site_addr} && echo "正常" || echo "异常")
site_status=$([ ${check_type} == 2 ] && curl -s -o /dev/null ${site_addr} && echo "正常" || echo "异常")
# 信息输出
echo
echo -e "\e[31m\t站点状态信息\e[0m"
echo -e "\e[32m================================"
echo "${site_addr} 站点状态: ${site_status}"
echo -e "================================\e[0m"
脚本执行效果
[root@localhost ~]# /bin/bash site_healthcheck.sh
请输入待测试站点域名
[root@localhost ~]# /bin/bash site_healthcheck.sh aa bb
请保证输入1个脚本参数
[root@localhost ~]# /bin/bash site_healthcheck.sh www.baidu.com
-----------检测平台支持的检测类型-----------1: wget2: curl
----------------------------------------
请输入网站的检测方法: 1站点状态信息
================================
www.baidu.com 站点状态: 异常
================================
[root@localhost ~]# /bin/bash site_healthcheck.sh www.baidu.com1
-----------检测平台支持的检测类型-----------1: wget2: curl
----------------------------------------
请输入网站的检测方法: 2站点状态信息
================================
www.baidu.com1 站点状态: 异常
================================
小结
户名或密码有误"
脚本执行效果
[root@localhost ~]# /bin/bash simple_jumpserver.sh欢迎使用堡垒机-----------请选择你要登录的远程主机-----------1: 10.0.0.14 (nginx)2: 10.0.0.15 (tomcat)3: 10.0.0.19 (apache)q: 使用本地主机
----------------------------------------------请输入您要选择的远程主机编号: q
请输入登录本地主机的用户名: root
请输入登录本地主机的密码:
主机登录验证成功
[root@localhost ~]# /bin/bash simple_jumpserver.sh欢迎使用堡垒机-----------请选择你要登录的远程主机-----------1: 10.0.0.14 (nginx)2: 10.0.0.15 (tomcat)3: 10.0.0.19 (apache)q: 使用本地主机
----------------------------------------------请输入您要选择的远程主机编号: q
请输入登录本地主机的用户名: python
请输入登录本地主机的密码:
您输入的用户名或密码有误
信息检测
脚本功能-检测公司网站的存活
判断网站的命令
[root@localhost ~]# wget --spider -T5 -q -t2 www.baidu.com
[root@localhost ~]# echo $?
0
[root@localhost ~]# wget --spider -T5 -q -t2 www.baidu.com1
[root@localhost ~]# echo $?
4
[root@localhost ~]# curl -s -o /dev/null www.baidu.com
[root@localhost ~]# echo $?
0
[root@localhost ~]# curl -s -o /dev/null www.baidu.com1
[root@localhost ~]# echo $?
6
脚本的核心内容
[root@localhost ~]# cat site_healthcheck.sh
#!/bin/bash
# 功能:定制站点的检测功能
# 版本:v0.1
# 作者:书记
# 联系:www.superopsmsb.com# 定制普通变量
site_addr="$1"
# 脚本基本判断
[ -z ${site_addr} ] && echo "请输入待测试站点域名" && exit
[ $# -ne 1 ] && echo "请保证输入1个脚本参数" && exit# 检测平台的信息提示
echo -e "\e[32m-----------检测平台支持的检测类型-----------1: wget2: curl
----------------------------------------"'\033[0m'# 选择检测类型
read -p "请输入网站的检测方法: " check_type
site_status=$([ ${check_type} == 1 ] && wget --spider -T5 -q -t2 ${site_addr} && echo "正常" || echo "异常")
site_status=$([ ${check_type} == 2 ] && curl -s -o /dev/null ${site_addr} && echo "正常" || echo "异常")
# 信息输出
echo
echo -e "\e[31m\t站点状态信息\e[0m"
echo -e "\e[32m================================"
echo "${site_addr} 站点状态: ${site_status}"
echo -e "================================\e[0m"
脚本执行效果
[root@localhost ~]# /bin/bash site_healthcheck.sh
请输入待测试站点域名
[root@localhost ~]# /bin/bash site_healthcheck.sh aa bb
请保证输入1个脚本参数
[root@localhost ~]# /bin/bash site_healthcheck.sh www.baidu.com
-----------检测平台支持的检测类型-----------1: wget2: curl
----------------------------------------
请输入网站的检测方法: 1站点状态信息
================================
www.baidu.com 站点状态: 异常
================================
[root@localhost ~]# /bin/bash site_healthcheck.sh www.baidu.com1
-----------检测平台支持的检测类型-----------1: wget2: curl
----------------------------------------
请输入网站的检测方法: 2站点状态信息
================================
www.baidu.com1 站点状态: 异常
================================
小结
相关文章:
shell脚本编程实践第2天
1 内容格式化 1.1 输出格式化 1.1.1 echo解读 学习目标 这一节,我们从 基础知识、简单实践、小结、三个方面来学习。 基础知识 命令简介 echo命令的功能是将内容输出到默认显示设备,一般起到一个提示的作用。OPTIONS: -n 不要在最后自…...
wgcloud-server端部署说明
Wgcloud 是一款开源的轻量级服务器监控系统,支持多平台,可对服务器的 CPU、内存、磁盘、网络等指标进行实时监控。 以下是 Wgcloud Server端的详细部署步骤: 环境准备 服务器: 至少准备两台服务器,一台作为监控端&a…...
AES/CBC/PKCS5Padding加密
1、加密代码如下 public static String encryptAEs_CBC(String data,String key,byte[] iv) {Cipher cipher = null;try {cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");//位数不够,自动补一个长度int blocksize = cipher.getBlockSize();byte[] dataBytes …...
9.8 Visual Studio 2022安装Qt 和安装graphic
1.安装Qt 1. 安装Qt 首先打开Visual Studio,然后创建一个项目,再在最上面的一行依次打开“扩展-->管理扩展”,再在搜索框内搜索“QT”,显示如下界面: 再在右边QT右边有个“在浏览器中查看”,打开后出现…...
【C++设计模式】第四篇:建造者模式(Builder)
注意:复现代码时,确保 VS2022 使用 C17/20 标准以支持现代特性。 分步骤构造复杂对象,实现灵活装配 1. 模式定义与用途 核心目标:将复杂对象的构建过程分离,使得同样的构建步骤可以创建不同的表示形式。 常见场景&am…...
Spring Boot如何利用Twilio Verify 发送验证码短信?
Twilio提供了一个名为 Twilio Verify 的服务,专门用于处理验证码的发送和验证。这是一个更为简化和安全的解决方案,适合需要用户身份验证的应用。 使用Twilio Verify服务的步骤 以下是如何在Spring Boot中集成Twilio Verify服务的步骤: 1.…...
制造业中的“大数据”:如何实现精准决策?
在当今全球经济竞争日趋激烈、技术变革周期不断缩短的环境下,制造业面临着全新的挑战和机遇。随着信息技术的飞速发展,“大数据”正以前所未有的速度渗透到制造业的各个环节,帮助企业实现更精准的决策、更灵活的生产组织以及更敏捷的市场响应…...
Linux cat 命令
cat(英文全拼:concatenate)命令用于连接文件并打印到标准输出设备上,它的主要作用是用于查看和连接文件。 使用权限 所有使用者 语法格式 cat [选项] [文件] 参数说明: -n:显示行号,会在输…...
CSS—flex布局、过渡transition属性、2D转换transform属性、3D转换transform属性
1.flex布局 也叫弹性布局,是浏览器提倡的布局模型,非常适合结构化布局,提供了强大的空间分布和对齐能力,不会产生浮动布局中脱标现象,布局网页更简单,更灵活。 flex容器属性: 属性描述d…...
Java UDP 通信:实现简单的 Echo 服务器与客户端
在计算机网络编程中,UDP(User Datagram Protocol)是一种无连接的传输层协议,它允许应用程序在不建立连接的情况下发送数据包。与 TCP 不同,UDP 不保证数据包的顺序、可靠性或完整性,但它具有低延迟和低开销…...
使用GitLink个人建站服务部署Allure在线测试报告
更多技术文章,访问软件测试社区 文章目录 🚀前言🔑开通GitLink个人建站服务1. 前提条件2. 登录GitLink平台(https://www.gitlink.org.cn/login)3. 进入设置>个人建站>我的站点4. 新建站点5. 去仓部进行部署6. 安…...
Mybatis plus异常: type `java.time.LocalDateTime` not supported by default
1、问题: Java数据库实体对象有字段如下: TableField(typeHandler JacksonTypeHandler.class) private Map<String, Object> dataDetail; 如果dataDetail中有LocalDateTime对象,在保存时会报如下异常: Caused by: com.…...
Django:文件上传时报错in a frame because it set ‘X-Frame-Options‘ to ‘deny‘.
即:使用Content-Security-Policy 1.安装Django CSP中间件: pip install django-csp 2.更改项目配置: # settings.py MIDDLEWARE [...csp.middleware.CSPMiddleware,... ]CSP_DEFAULT_SRC ("self",) CSP_FRAME_ANCESTORS (&q…...
腾讯云 | 微搭低代码快速开发数据表单应用
如上所示,登录腾讯云微搭低代码业务控制台,开始新创建一个应用,创建应用的方式包括,根据实际的业务需求,从模版列表中选择一个模板填入数据模型创建新应用,使用微搭组件自主设计数据模型创建新应用…...
【RabbitMQ】RabbitMQ的核心概念与七大工作模式
🔥个人主页: 中草药 🔥专栏:【中间件】企业级中间件剖析 在现代分布式系统和微服务架构中,消息队列(Message Queue) 是解决服务间通信、系统解耦和流量削峰的关键技术之一。而 RabbitMQ 作为一…...
金蝶ERP星空对接流程
1.金蝶ERP星空OPENAPI地址: 金蝶云星空开放平台 2.下载金蝶云星空的对应SDK包 金蝶云星空开放平台 3.引入SDK流程步骤 引入Kingdee.CDP.WebApi.SDK 右键项目添加引用,在打开的引用管理器中选择浏览页签,点击浏览按钮,找到从官…...
【C++】基于范围的for循环(range-based for loop)
一. std::vector 元素排布顺序 在 C 中,std::vector 是一个动态数组,用于存储同类型元素的序列。当你向 std::vector 中添加元素时(通常通过 push_back 方法),元素是按照你添加它们的顺序排列的。 具体来说ÿ…...
下载b站视频音频
文章目录 方案一:jjdown如何使用 方案二:bilibili哔哩哔哩下载助手如何使用进入插件网站插件下载插件安装 使用插件下载视频音频:复制音频下载地址 方案三:bat命令下载单个音频下载单个视频下载单个音视频 方案一:jjdo…...
LabVIEW DataSocket 通信库详解
dataskt.llb 是 LabVIEW 2019 内置的核心函数库之一,位于 vi.lib\Platform\ 目录下,专注于 DataSocket 技术的实现。DataSocket 是 NI 提供的网络通信协议,支持跨平台、跨设备的实时数据共享,广泛应用于远程监控、分布式系统集成等…...
金融项目实战
测试流程 测试流程 功能测试流程 功能测试流程 需求评审制定测试计划编写测试用例和评审用例执行缺陷管理测试报告 接口测试流程 接口测试流程 需求评审制定测试计划分析api文档编写测试用例搭建测试环境编写脚本执行脚本缺陷管理测试报告 测试步骤 测试步骤 需求评审 需求评…...
初始网络编程
什么是网络编程? 在网络通信协议下,不同计算机上运行的程序,进行的数据传输。 应用场景:即时通信、网游对战、金融证券、 国际贸易、邮件、等等。 不管是什么场景,都是计算机跟计算机之间通过网络进行数据传输。 …...
编译可以在Android手机上运行的ffmpeg程序
下载代码 git clone gitgithub.com:FFmpeg/FFmpeg.git git checkout n7.0建立build目录 mkdir build cd build创建build.sh脚本 vim build.sh这段脚本的主要功能是配置和编译 FFmpeg,使其能够在 Android 平台上运行,通过设置不同的架构和 API 级别&am…...
使用Kubernetes部署Spring Boot项目
目录 前提条件 新建Spring Boot项目并编写一个接口 新建Maven工程 导入 Spring Boot 相关的依赖 启动项目 编写Controller 测试接口 构建镜像 打jar包 新建Dockerfile文件 Linux目录准备 上传Dockerfile和target目录到Linux 制作镜像 查看镜像 测试镜像 上传镜…...
LC77. 组合
LC77. 组合 题目要求(一)回溯1. 解决思路2. 具体步骤3. 代码实现4. 复杂度分析5. 示例解释示例 1:示例 2: 6. 总结 LC77. 组合 题目要求 (一)回溯 要解决这个问题,我们需要生成从 [1, n] 范围内选择 k 个数的所有可能组合。组合的顺序不重要…...
Android中的ANR(Application Not Responding)现象
Android中的ANR(Application Not Responding)现象是指应用程序未能在规定的时间内响应系统或用户的输入事件,从而触发系统弹出的无响应对话框。以下是关于ANR现象的详细解释: 一、ANR现象的定义 ANR通常发生在以下情况ÿ…...
操作系统启动——前置知识预备
文章目录 1. 理解冯诺依曼体系结构1.1 简单见一见冯诺依曼1.2 进一步认识1.3 为什么一定要有内存的存在? 2. 操作系统2.1 概念2.2 设计OS的目的2.3 OS的核心功能2.4 如何理解“管理”二字?(小故事版)2.5 系统调用和库函数概念 3. 进程简述3.1 基本概念3.…...
Unity中VFX烟雾特效与场景中的碎片物体重叠时闪烁问题
双击Unity项目中vfx特效文件,选中VFX编辑器中的Output Particle节点,看右侧的Inspector窗口 这个图的BlendMode是Alpha, 意味着渲染队列是3000要关闭Z Write Mode, 其值设置为off最后一个属性Sorting Priorty 设置为50,意味着渲染队列在3000…...
[RN]React Native知识框架图详解
React Native 是一个基于 React 的跨平台移动应用开发框架。以下是 React Native 知识框架图的详细解析: React Native 知识框架 1. 核心概念 JSX:JavaScript XML 语法,类似 HTML 的语法,用于描述 UI 组件。组件(Com…...
每日OJ_牛客_游游的字母串_枚举_C++_Java
目录 牛客_游游的字母串_枚举 题目解析 C代码 Java代码 牛客_游游的字母串_枚举 游游的字母串 描述: 对于一个小写字母而言,游游可以通过一次操作把这个字母变成相邻的字母。a和b相邻,b和c相邻,以此类推。特殊的࿰…...
解锁MacOS开发:环境配置与应用开发全攻略
✨✨✨这里是小韩学长yyds的BLOG(喜欢作者的点个关注吧) ✨✨✨想要了解更多内容可以访问我的主页 小韩学长yyds-CSDN博客 目录 引言 一、MacOS 开发环境配置 (一)必备工具安装 (二)集成开发环境(IDE)选…...
IDEA 2025最新版2024.3.3软件安装、插件安装、语言设置
IntelliJ IDEA是一款由JetBrains公司开发的集成开发环境(IDE),主要用于Java语言的开发,它通过提供丰富的功能如智能代码补全、代码分析、版本控制集成等来提高开发效率。 IDEA有社区版和专业版两个版本,社区版是免费开…...
leetcode 0018 四数之和-medium
1 题目:四数之和 给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复&#x…...
Ubuntu 下 nginx-1.24.0 源码分析 - ngx_conf_add_dump
ngx_conf_add_dump 定义在src\core\ngx_conf_file.c static ngx_int_t ngx_conf_add_dump(ngx_conf_t *cf, ngx_str_t *filename) {off_t size;u_char *p;uint32_t hash;ngx_buf_t *buf;ngx_str_node_t *sn;ngx_conf_dump_t *cd;has…...
家政预约小程序用例图分析
在和客户进行需求沟通的时候,除了使用常规的问答的形式,我还使用图形化工具更深入的沟通。比如借助UML的用例图来开展系统分析,并且按照角色详细拆解了家政预约小程序的各个用例。在分析阶段思考的越多,沟通的越多,在系…...
unity学习62,尝试做第一个小游戏项目:flappy bird
目录 学习参考 1 创建1个unity 2D项目 1.1 2D项目模板选择 1.1.1 2D(built-in-Render pipeline) 1.1.2 universe 2D 1.1.3 这次选择 2D(built-in-Render pipeline) 1.2 创建项目 1.2.1 注意点 1.2.2 如果想修改项目名 2 导入美术资源包 2.1 下载一个flappy bird的…...
Windows10下本地搭建Manim环境
文章目录 1. 简介2. Python环境3. uv工具4. Latex软件5. 安装Manim数学库6. 中文支持参考 1. 简介 manim是个一科普动画的库, 本文用到的是社区版本。 2. Python环境 这个不用多说,可以参考其他的文章。记得把pip也安上。 3. uv工具 上面的pip是老…...
zabbix“专家坐诊”第277期问答
在线答疑:乐维社区 问题一 Q:这个怎么解决呢? A:缺少这个依赖。 Q:就一直装不上。 A:装 zabbix-agent2-7.0.0-releasel.el7.x86 64 需要前面提示的那个依赖才可以装。 问题二 Q:大佬,如果agen…...
解决git clone下载慢或者超时问题
在网上找了很多办法,直接最简单的使用镜像网站下载。 国内可用的镜像网站有: https://github.com.cnpmjs.org # 服务器位于香港https://gitclone.com # 服务器位于杭州https://doc.fastgit.org # 服务器位于香港 例如:将 git clone https:…...
机器学习:强化学习的epsilon贪心算法
强化学习(Reinforcement Learning, RL)是一种机器学习方法,旨在通过与环境交互,使智能体(Agent)学习如何采取最优行动,以最大化某种累积奖励。它与监督学习和无监督学习不同,强调试错…...
MySQL-高级查询
查询处理 排序(默认不是按主键排序的) order by 字段1[,字段2] [asc|desc] 默认是升序排序也可以指定 select 列表中列的序号进行排序如果是多个字段,那么在上一个字段排序完的基础上排序下一个 限制数量 limit 行数࿰…...
NModbus 连接到Modbus服务器(Modbus TCP)
1、在项目中通过NuGet添加NModbus,在界面中添加一个Button。 using NModbus.Device; using NModbus; using System.Net.Sockets; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Docu…...
value_counts()和unique()
我今天发现一个很有意思的问题哈 import scanpy as sc import numpy as npX np.random.randn(10,3) adata1 sc.AnnData(X) adata1.obs["sample"] "H1" print(adata1)X np.random.randn(20,3) adata2 sc.AnnData(X) adata2.obs["sample"] &…...
FinRobot:一个使用大型语言模型进行金融分析的开源AI代理平台
文章目录 前言一、生态系统1. 金融AI代理(Financial AI Agents)2. 金融大型语言模型(Financial LLMs)3. LLMOps4. 数据操作(DataOps)5. 多源LLM基础模型(Multi-Source LLM Foundation Models&am…...
示例:在WPF中如何使用Segoe MDL2 Assets图标和使用该图标的好处
一、目的:分享在WPF中如何使用Segoe MDL2 Assets图标和使用该图标的好处 在WPF中使用Segoe MDL2 Assets字体,可以通过设置控件的FontFamily属性来实现。Segoe MDL2 Assets是一个包含许多图标的字体,通常用于Windows应用程序的图标显示。 二、…...
使用UA-SPEECH和TORGO数据库验证自动构音障碍语音分类方法
使用UA-SPEECH和TORGO数据库验证自动构音障碍语音分类方法 引言 原文:On using the UA-Speech and TORGO databases to validate automatic dysarthric speech classification approaches 构音障碍简介 构音障碍是一种由于脑损伤或神经疾病(如脑瘫、肌萎缩侧索硬化症、帕金森…...
容器与虚拟机:云时代的底层架构博弈
容器与虚拟机:云时代的底层架构博弈 在数字化浪潮席卷的当下,云技术已成为企业和开发者不可或缺的基础设施。在云环境中,容器和虚拟机作为两种关键的底层技术,犹如双子星般备受瞩目。它们究竟谁能在这场技术较量中脱颖而出&#x…...
解决android studio(ladybug版本) gradle的一些task突然消失了
今天不知道干了啥,AS(ladybug版本)右边gradle的task有些不见了,研究了半天解决了,这里记录下: 操作: File -->Settings-->Experimental--> 取消选项“Enable support for multi-vari…...
Wpf-ReactiveUI-Usercontrol交互
文章目录 1、使用属性绑定UserControl 部分(MyUserControl.xaml.cs)UserControl 视图模型部分(MyUserControlViewModel.cs)主界面部分(MainWindow.xaml)主界面视图模型部分(MainWindowViewModel.cs)2、使用消息传递UserControl 视图模型部分(MyUserControlViewModel.c…...
Unity插件-Mirror使用方法(四)组件介绍(Network Manager HUD)
目录 一、插件介绍 二、主要组件 Network Manager 三、Network Manager HUD 1、组件介绍 2、NetworkManagerHUD 的核心功能 快速操作按钮 状态信息显示 场景切换支持 调试辅助 3、关键属性与配置 4、HUD 界面详解 【主机模式(服务器客户端)…...
UDP协议(20250303)
1. UDP UDP:用户数据报协议(User Datagram Protocol),传输层协议之一(UDP,TCP) 2. 特性 发送数据时不需要建立链接,节省资源开销不安全不可靠的协议 //一般用在实时性比较高…...