3、shell格式化

常用符号

信息传递

重定向

重定向符号

在shell脚本中有两类常见的重定向符号:
覆盖式重定向:
	> 表示将符号左侧的内容,以覆盖的方式输入到右侧文件中
	< 表示将符号右侧的内容,以覆盖的方式输入到左侧文件中
追加式重定向:
	>> 表示将符号左侧的内容,以追加的方式输入到右侧文件的末尾行中
	<< 表示将符号右侧的内容,以追加的方式输入到左侧文件的末尾行中

实践1 - 覆盖式重定向

查看文件内容
[root@localhost ~]# cat file.txt
nihao

使用重定向符号给文件中增加内容
[root@localhost ~]# echo "file1.txt" > file.txt

再次查看文件内容
[root@localhost ~]# cat file.txt
file1.txt

image

实践2 - 追加式重定向

查看文件内容
[root@localhost ~]# cat file.txt 
file1.txt

使用重定向符号给文件中增加内容
[root@localhost ~]# echo "file2.txt" >> file.txt 

再次查看文件内容
[root@localhost ~]# cat file.txt 
file1.txt
file2.txt

image

管道符

符号简介

| 这个就是管道符,常用于将两个命令隔开,然后命令间(从左向右)传递信息使用的。

使用格式

命令1 | 命令2
	管道符左侧命令1 执行后的结果,传递给管道符右侧的命令2使用

实践1 - 信息的传递

查看当前系统中的全局变量SHELL
[root@localhost ~]# env | grep SHELL
SHELL=/bin/bash

image

终端输出

后台执行

简介

& 就是将一个命令从前台转到后台执行,使用格式如下:
	命令 &

简单演示

前台执行休眠命令
[root@localhost ~]# sleep 4
界面卡住4秒后消失

后台执行休眠命令
[root@localhost ~]# sleep 10 &
[1] 4198
[root@localhost ~]# ps aux | grep sleep
root       4198  0.0  0.0   9032   808 pts/17   S    21:58   0:00 sleep 10
root       4200  0.0  0.0  15964   944 pts/17   S+   21:58   0:00 grep --color=auto sleep

image

信息符号

信息简介

1 表示正确输出的信息
2 表示错误输出的信息
2>&1 代表所有输出的信息,也可以简写为 "&>"

示例1 - 符号演示

标准正确输出重定向到zhengque文件
[root@localhost ~]# cat nihao.txt 1>> zhengque.txt

标准错误输出重定向到errfile文件
[root@localhost ~]# dsfadsfadsfa 2>> errfile.txt

实例2 - 综合演练

脚本文件内容
[root@localhost ~]# cat ceshi.sh
#!/bin/bash
# 输出正确信息
echo '下一条错误命令'
# 执行错误命令,输出错误信息
dsfsafsafdsa

脚本执行效果
[root@localhost ~]# /bin/bash ceshi.sh
下一条错误命令
ceshi.sh:行5: dsfsafsafdsa: 未找到命令
1 和 2 综合演练
[root@localhost ~]# /bin/bash ceshi.sh 1>> ceshi-ok 2>> ceshi-err
[root@localhost ~]# cat ceshi-ok
下一条错误命令
[root@localhost ~]# cat ceshi-err
ceshi.sh:行5: dsfsafsafdsa: 未找到命令
全部信息演练
[root@localhost ~]# /bin/bash ceshi.sh >> ceshi-all 2>&1
[root@localhost ~]# cat ceshi-all
下一条错误命令
ceshi.sh:行5: dsfsafsafdsa: 未找到命令

image

输入格式化

EOF

基础知识

场景需求

	在运维岗位中,有非常多的场景需要我们在脚本中编写应用软件的配置文件。在这些应用软件的配置文件中,经常携带大量的格式,尤其是携带空格的层级格式,如果我们一个一个的编写好标准的配置文件,但是一旦涉及到场景信息的动态化调整,固定好的配置文件就不太适合了,所以我们需要一种方法能够实现整个动态的格式化需求。

解决方法

	在shell编程中,"EOF”通常与"<<”结合使用,"<<EOF”表示后续的输入作为子命令或子shell的输入,直到遇到"EOF”,再次返回到主调用shell,可将其理解为分界符(delimiter)。
	所谓的 EOF,就是End of file的缩写,它是一种自定义的文件内容终止符。
	既然是分界符,那么形式自然不是固定的,这里可以将”EOF"可以进行自定义,但是前后的”EOF"必须成对出现且不能和shell命令冲突。其使用形式如下:

语法格式

交互式程序 << EOF
command1
command2
...
EOF
注意:
	最后的"EOF"必须单独占一行,而且必须顶格写,如果不想受到如此限制的话,使用<<-符号
		<<- 的作用是自动去除最后一个EOF前面的制表符\t【注意,对于空格无效】
	前后两个EOF可以是任意一个字符,比如aaa,只要前后两个边界内容一致即可。
	"EOF"中间的内容将以标准输入的形式输入到”交互式程序",当shell看到”<<"知道其后面输入的分界符,当shell再次看到分界符时,两个分界符中间的部分将作为标准输入。

简单实践

实践1 - EOF信息格式化输出

终端方式接收多行信息,然后交个一个命令
[root@localhost ~]# cat << EOF
> Dear Wang:
>   jian dao ni hen gaoxing.
> danshi wo bu xihuan ni.
> zaijian.
>                zhaoliu
>                2100-11-11
> EOF
Dear Wang:
  jian dao ni hen gaoxing.
danshi wo bu xihuan ni.
zaijian.
               zhaoliu
               2100-11-11

image

实践2 - 脚本中实践EOF

编写请假条
[root@localhost ~]# cat qingjiatiao.sh
#!/bin/bash
# EOF演示请假条示例

cat << EOF
                        请假条
王老师:
    我因患急性空腹病,现在需要到火锅理疗,不能到学校上课,
请准假一天。恳请批准!
                                             请假人:李四
                                                 6月1日
EOF

执行脚本示例
[root@localhost ~]# /bin/bash qingjiatiao.sh
                        请假条
王老师:
    我因患急性空腹病,现在需要到火锅理疗,不能到学校上课,
请准假一天。恳请批准!
                                             请假人:李四
                                                 6月1日

image

实践3 - 末尾EOF前面有制表符

修改脚本
[root@localhost ~]# cat qingjiatiao.sh
...
# EOF前面有一个制表符,也就是 Tab键效果,切记不是空格,是Tab,如果使用空格就把EOF 当成了注释的内容
	EOF
	
执行脚本后效果
[root@localhost ~]# /bin/bash qingjiatiao.sh
qingjiatiao.sh:行11: 警告:立即文档在第 4 行被文件结束符分隔 (需要 `EOF')
...
修改脚本效果
[root@localhost ~]# cat qingjiatiao.sh
#!/bin/bash
# EOF演示请假条示例,将<< 替换为 <<-

cat <<- EOF
                        请假条
王老师:
    我因患急性空腹病,现在需要到火锅理疗,不能到学校上课,
请准假一天。恳请批准!
                                             请假人:李四
                                                 6月1日
        EOF
脚本执行后的效果
[root@localhost ~]# /bin/bash qingjiatiao.sh
                        请假条
王老师:
    我因患急性空腹病,现在需要到火锅理疗,不能到学校上课,
请准假一天。恳请批准!
                                             请假人:李四
                                                 6月1日

cat

实现多行文件的输出

语法格式
    cat > file  << EOF
    ...
    EOF
注意:
	> 代表覆盖式增加内容到 file 文件
	>> 代表追加式增加内容到 file 文件

简单示例

定制主机解析名信息
[root@localhost ~]# cat >> hosts << EOF
10.0.0.13 k8s-master
10.0.0.14 k8s-node1
10.0.0.15 k8s-node2
EOF

演示效果
[root@localhost ~]# cat hosts
10.0.0.13 k8s-master
10.0.0.14 k8s-node1
10.0.0.15 k8s-node2

image

实践1- 定制nginx配置文件

定制nginx配置文件的脚本
[root@localhost ~]# cat define-nginx-conf.sh
#!/bin/bash
# 定制nginx的配置文件

# 定制配置文件目录
NGINX_DIR='/data/server/conf'
NGINX_CONF='nginx.conf'

# 创建基本目录
mkdir -p $NGINX_DIR

# 定制nginx配置文件
cat > $NGINX_DIR/$NGINX_CONF << EOF
server {
  listen 80;
  server_name www.example.com
  listen / {
     proxy_pass http://10.0.0.12:10086;
  }
}
EOF
执行文件后的效果
[root@localhost ~]# /bin/bash define-nginx-conf.sh
[root@localhost ~]# cat /data/server/conf/nginx.conf
server {
  listen 80;
  server_name www.example.com
  listen / {
     proxy_pass http://10.0.0.12:10086;
  }
}

image

tee

功能简介

	tee命令读取标准输入,把这些内容同时输出到标准输出和(多个)文件中,tee命令可以重定向标准输出到多个文件。要注意的是:在使用管道线时,前一个命令的标准错误输出不会被tee读取。

命令格式

样式1:只输出到标准输出
	tee
样式2:输出到标准输出的同时,保存到文件file中
	tee file
样式3:输出到标准输出的同时,追加到文件file中。如果文件不存在则创建;如果文件存在则追加。
	tee -a file
	tee host2 <<- EOF ... EOF
样式4: 输出到标准输出两次。
	tee -
样式5:输出到标准输出两次,同时保存到file1和file2中。
	tee file1 file2 -

简单演示

实践1 - 仅输出到当前屏幕
[root@localhost ~]# echo tee-test | tee
tee-test

实践2 - 同时输出到屏幕和文件
[root@localhost ~]# echo tee-test | tee tee-file
tee-test
[root@localhost ~]# cat tee-file
tee-test

image

实践3 - 追加到对应的文件中
[root@localhost ~]# cat tee-file
tee-test
[root@localhost ~]# echo tee-test1 | tee tee-file
tee-test1
[root@localhost ~]# cat tee-file
tee-test1
[root@localhost ~]# echo tee-test2 | tee -a tee-file
tee-test2
[root@localhost ~]# cat tee-file
tee-test1
tee-test2

image

实践4 - 输出多次信息,多一个 - 就多输出一次到屏幕显示
[root@localhost ~]# echo tee-test | tee
tee-test
[root@localhost ~]# echo tee-test | tee -
tee-test
tee-test
[root@localhost ~]# echo tee-test | tee - -
tee-test
tee-test
tee-test
[root@localhost ~]# echo tee-test | tee - - -
tee-test
tee-test
tee-test
tee-test
实践5 - 保存到多个文件
[root@localhost ~]# echo tee-test | tee file-1 file-2 file-3
tee-test
[root@localhost ~]# cat file-1
tee-test
[root@localhost ~]# cat file-2
tee-test
[root@localhost ~]# cat file-3
tee-test
实践6 - 接收命令行多行信息,同时在文件和当前终端显示
[root@localhost ~]# tee host2 <<- EOF
> 10.0.0.13 k8s-master
> 10.0.0.14 k8s-node1
> 10.0.0.15 k8s-node2
> EOF
10.0.0.13 k8s-master
10.0.0.14 k8s-node1
10.0.0.15 k8s-node2

查看文件内容
[root@localhost ~]# cat host2
10.0.0.13 k8s-master
10.0.0.14 k8s-node1
10.0.0.15 k8s-node2

image

案例实践 - kubernetes参数配置

定制kubernetes的网络模块加载
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF

定制kubernetes的数据包内核参数
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sudo sysctl --system

image

输出格式化

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.

image

实践3 - 特殊符号的输出

使用 -e 选项启用转义字符的解析
[root@localhost ~]# echo -e "The 2021 State of DevOps Report\n\t- is here"
The 2021 State of DevOps Report
        - is here

image

实践4 - 内容的拼接

使用 -n 选项启用信息输出不换行
[root@localhost ~]# echo -n hello;echo world
helloworld

image

字体颜色

基础知识

场景需求

echo本质上是将信息内容输出到当前的屏幕终端,如果只是一种颜色的话,可能导致视觉疲劳。所以,一般情况下,我们在显示信息的时候,往往会通过颜色的方式实现特定内容的颜色高亮显示。

echo命令可以修改字体类型,字体背景色以及字体颜色,转义序列\033可以用于改变字体属性。

格式解读

格式如下:
	echo -e "\033[字背景颜色;文字颜色m字符串\033[0m"
	echo -e "\033[41;36m 显示的内容 \033[0m"

image

颜色分类

色彩 绿
字体色 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"

image

实践2 - 信息颜色显示

定制堡垒机的测试页面脚本
[root@localhost ~]# cat simple_jumpserver.sh
#!/bin/bash
# 功能:定制堡垒机的展示页面
# 作者:wangshuji
# 版本:V0.1
# 联系: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'
echo -e "请输入您要选择的远程主机编号: "

image
执行脚本:
image

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] 格式 [参数]

image
就是占位符而已

格式化替换符
	常用:
    %s 		字符串
    %d,%i 	十进制整数
    %f 		浮点格式
    %% 		表示%本身
	
	不常用:
    %c 		ASCII字符,即显示对应参数的第一个字符
    %b 		相对应的参数中包含转义字符时,可以使用此替换符进行替换,对应的转义字符会被转义
    %o 		八进制值
    %u 		不带正负号的十进制值
    %x 		十六进制值(a-f)
    %X 		十六进制值(A-F)
格式化转义符号
	常用:
	\n		换行
    \r		回车(Carriage return)
    \t		水平制表符
	\\		一个字面上的反斜杠字符
	
	不常用:
    \a		警告字符,通常为ASCII的BEL字符
    \b		后退
    \c		抑制(不显示)输出结果中任何结尾的换行字符
    \f		换页(formfeed)
    \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 ~]#

image

实践2 - 替换符号演示

基本信息演示 - 单引号和双引号效果一样
[root@localhost ~]# printf "姓名:%s, 语文:%d, 数学:%d\n" "张三" 89 98
姓名:张三, 语文:89, 数学:98
[root@localhost ~]# printf '姓名:%s, 语文:%d, 数学:%d\n' "张三" 89 98
姓名:张三, 语文:89, 数学:98
注意:
	相关信息会按照顺序依次替换到格式化的替换符位置

image

数字格式展示
[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代表小数点后面的可显示的位数。

image

实践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填充,实现格式化

image

实践5 - 环境变量的使用

定制环境变量
[root@localhost ~]# VAR1=hello; VAR2=shell

颜色显示
[root@localhost ~]# printf "\033[32m%s \033[31m%s\033[0m\n" $VAR1 $VAR2
hello shell

image

综合案例

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
posted @ 2023-01-16 22:27  aBiu--  阅读(318)  评论(0编辑  收藏  举报