1. openssl实现加解密、哈希

1.1 openssl实现AES加解密

  • 老大说,不能在shell脚本放明文密码
  • 自己的第一反应:我先在本地AES加密得到密文,然后将密文写入shell脚本
  • 网上搜索了一下,openssl可以满足需求
  • 直接基于字符串加解密(AES-256)
# 直接基于字符串加密
echo "明文" | openssl enc -aes-256-cbc -a -salt -pass pass:密码

# 直接基础字符串解密, -d表示解密
echo "密文" | openssl enc -aes-256-cbc -a -d -salt -pass pass:密码
  • 示例
echo "hello, world" | openssl enc -aes-256-cbc -a -salt -pass pass:12345678

echo "U2FsdGVkX1+8LczdI2MWVt4rW7VLxCYgCcQcftPwvqg=" | openssl enc -aes-256-cbc -a -d -salt -pass pass:12345678
  • 对文件进行AES加解密
# 文件加密
openssl enc -aes-256-cbc -a -salt -pass pass:123456 -in source_file_name -out target_file_name

# 文件解密
openssl enc -aes-256-cbc -a -d -salt -pass pass:123456 -in source_file_name -out target_file_name
  • 示例
# 文件加密
openssl enc -aes-256-cbc -a -salt -pass pass:123456 -in hello.txt -out hello.txt.enc

# 文件解密
openssl enc -aes-256-cbc -a -d -salt -pass pass:123456 -in hello.txt.enc -out hello

1.2 openssl实现SHA-256计算

  • 计算SHA-256
# 基于文件计算SHA-256
openssl dgst -sha256 file_name
# 基于字符串计算SHA-256
echo "明文" | openssl dgst -sha256
  • 示例
# 基于文件计算SHA-256
openssl dgst -sha256 hello.txt 
# 基于字符串计算SHA-256
echo "hello" | openssl dgst -sha256

参考链接

  • shell 脚本明文密码加密小工具(AES字符串加解密)
  • openssl加密文件或文件夹
  • 如何使用OpenSSL:哈希值、数字签名等

2. 安装软件

  • centos中,安装一个软件的命令如下
yum install xxx
  • 手动安装,我们发现可能需要输入一个y,去确认安装
  • shell加解密aes_shell加解密aes

  • 新需求:通过shell脚本去安装某些软件,如何避免交互输入?
  • 添加-y,表示对后续所有问题,都回答yes
yum install xxx -y
  • -y的作用:
  • shell加解密aes_sed_02

  • 参考文档:利用shell脚本自动安装软件

3. sed命令

  • sed命令跟awk一样,是一个非常强大的处理命令
  • 目前,自己使用到的具体应用场景如下:
  • 通过sed删除文件中匹配的行
  • 通过sed命令修改文件中匹配的行
  • 通过sed命令修改前一命令的执行结果等
  • 总的来说,就是通过sed命令实现字符串的修改

3.1 字符串替换

  • 直接修改字符串,例如将10.193.183.131改成10-193-183-131
  • s表示替换指定字符,
  • 末尾的g表示全面替换,类似Java String类的replaceAll,否则默认替换第一个匹配的字符
  • 整体写法:"s/source-string/target-string/g",表示使用 target-string 将匹配行中所有source-string
hostname -i | sed "s/\./-/g"

3.2 删除匹配行

  • 删除匹配行,末尾使用d选项
# 删除包含sunrise的行
echo "hello, lucy
hello, sunrise" | sed "/sunrise/d" 
# 执行结果
hello, lucy

3.3 基于文件的修改

  • 通过-i选项基于文件进行修改,如果怕直接修改出问题,可以 -iSUFFIX创建备份文件,SUFFIX是自定义的后缀名
# 文件内容
hello, world
sunrise lucy
10.193.24.145

# 以备份文件的形式进行修改
sed -i_bak_20220120 "s/\./-/g" test 
# 将创建test_bak_20220120备份文件,test内容修改如下
hello, world
sunrise lucy
10-193-24-145
  • 向文件中插入多行,通过\n实现
sed -i "s/hello, world/hello, jack\nhello, grace/g" test  
# 修改后的内容
hello, jack
hello, grace
sunrise lucy
10-193-24-145

3.4 正则匹配

  • -r正则匹配,如删除以hello开头的行
sed -ri "/^hello.*/d" test  
# 经过实践,不加r也是可以的
sed -i "/^hello.*/d" test  
# 修改后的内容
sunrise lucy
10-193-24-145
  • 例如,正则匹配,删除多余的空格
echo "   hello|   hadoop  | test" | awk -F '|' '{print $2}' | sed -r 's/( )+//g'
  • 其余可以参考:sed命令

3.5 如何插入变量?

  • 有时,我们希望将匹配到的内容,更新为一个变量中的内容
  • 可以直接在target-string部分,使用变量
ip=`hostname -i |sed 's/\./-/g'`
node_id="node.id=coordinator-"${ip}
sed -ri  "s/^node.id.*/${node_id}/g" $HOME/node.properties

3.6 其他小技巧汇总

  • 删除指定字符,如最后1个、开始的3个,使用.表示匹配一个任意字符,;实现多个操作指令的拼接。更多操作,见博客:使用 sed 命令替换/删除 文本字符的 20 个例子
# 删除最后一个字符
echo "250G" | sed -r "s/.{1}$//"
# 删除前3个字符
echo "123hello" | sed -r "s/...//"
# 删除最后一个x
echo "hellox" | sed -r "s/x$//"
# 同时删除前3个和最后一个字符
echo "123hellox" | sed -r "s/...//;s/x$//"

4. scp命令的小技巧

  • 使用scp在机器之间转发文件时,总是需要输入对方主机对应用户的密码
scp -r datard@10.193.121.12:/bigdata/presto-server-0.240.tar.gz /opt/bigdata/app/presto                 
Authorized uses only. All activity may be monitored and reported.
datard@10.193.121.12's password:
  • 如果是通过shell脚本实现scp,肯定不希望中途要求输入密码
  • 最好有个工具能提前输入密码,让scp命令自动执行,无需交互
  • sshpass是一个不错的工具
yum install -y  sshpass
  • 安装以后,便可以提前设置密码
sshpass -p "******" scp -r datard@10.193.121.12:/bigdata/presto/presto-server-0.240.tar.gz /opt/bigdata/app/presto
  • 而且,有时要需要弹出什么yes确认,通过scp的如下选项可以解决
-o 'StrictHostKeyChecking=no'
# 示例
scp -o 'StrictHostKeyChecking=no'  -r datard@10.193.121.12:/bigdata/presto/presto-server-0.240.tar.gz /opt/bigdata/app/presto

5. awk命令的使用

  • awk的由来:awk命令的作者为Aho、Weinberger和Kernighan,通过作者名字首字母组合得到了awk
  • 在我看来,awk命令就是按列处理文本数据的一个强大而实用的命令
  • 例如,可以按照指定的分隔符对文本进行分割,可以打印分割出来的任意列,可以求某列的最大值、最小值、和、平均值等
  • 关于awk命令的全面讲解,可以参考如下博客:
  • Awk Introduction Tutorial – 7 Awk Print Examples,文末附有其他的awk教程
  • Awk Tutorial Examples,awk教程的总目录

5.1 文本分割与打印

  • awk默认按照一个或者多个空格对每条记录(默认一行为一条记录)进行分割,分割后将产生多列,可以通过print打印想要的列
  • 文件test的内容如下:
100  Thomas  Manager    Sales       $5,000
200  Jason   Developer  Technology  $5,500
300  Sanjay  Sysadmin   Technology  $7,000
400  Nisha   Manager    Marketing   $9,500
500  Randy   DBA        Technology  $6,000

5.1.1 打印所有列(整条记录)

  • 使用awk进行分割并打印所有列,等价于cat命令。其中,$0表示整条记录
# 不指定具体的列,默认print所有列 
awk '{print;}' test      
# 或者
awk '{print}' test      
# 或者
awk '{print $0}' test
  • 执行结果:
  • shell加解密aes_sed_03

5.1.2 打印指定列

  • 使用awk进行分割并打印指定列
  • 其中,$N表示第N列,$0表示整条记录;NF是记录中的字段(列)数,$NF则表示最后一列
# 打印第二列和最后一列
awk '{print $2, $5}' test
# 或者
awk '{print $2, $NF}' test
  • 执行结果:

5.1.3 通过-F指定分割符

  • awk默认分割符为空格,可以通过-F指定分割符
# 以$作为分隔符,产生2列数据
awk -F '$' '{print $1, $2}' test
  • 执行结果
  • shell加解密aes_sed_04

  • -F对应awk的内建变量FS,上面的命令可以书写如下
awk 'BEGIN{FS="$";} {print $1, $2}' test

5.1.4 awk命令的整体结构

  • awk中,BEGIN用于定义对每条记录进行处理前的一些初始化工作,例如,定义变量、设置分割符等
  • END用于定义处理完所有记录后的一些收尾工作,例如,打印处理的记录总数,最大值、最小值等
  • BEGIN和END后面必须跟着使用{action1; action2; ...}表示的动作块(action part),不允许换行;如果换行,命令执行会报错!!
awk 'BEGIN 
	{FS="$";} 
	{print $1, $2}' test
  • 执行报错,提示BEGIN blocks must have an action part。
  • BEGIN和END动作块中间的动作块,则表示对每条记录进行的操作(自己喜欢称其为record action part)
  • 一个完整的awk命令示例如下:
# 整体结构为
begin action part [可选]
record action part [必须]
end action part [可选]
awk 'BEGIN{FS="$"}  
	{print $NF} 
	END{print "员工数:", NR}' test
  • 执行结果如下:

5.1.5 打印时,通过OFS指定列分割符

  • 通过以上命令的执行,我们不难发现:通过print打印每列时,依然使用空格作为分隔符
  • 有时,我们需要使用其他的分隔符。这时,可以使用awk的内建变量OFS指定打印时的分隔符
  • 以|作为列分割符
awk 'BEGIN{OFS=" | "} {print $1, $2, $NF}' test
  • 打印效果如下:
  • shell加解密aes_运维_05

5.2 求和、平均值、最大值、最小值

  • 首先,需要将test文本中,薪资列的,去除避免影响计算

5.2.1 求和

  • 实战:求员工薪水的和
# sum+=$NF,定义sum变量,并对薪资列进行累加求和
awk -F '$' '{sum+=$NF} END {print "员工薪水总和:", sum}' test
  • 执行结果:
  • shell加解密aes_linux_06

5.2.2 求平均

  • 求平均值,print时,使用sum / NR即可
  • 其中,NR表示处理过的记录条数,是一个不断变化的值,相当于每条记录的编号。
  • 当处理完最后一条记录时,NR对应的就是记录的总条数
  • 实战:求员工薪水的平均值
awk -F '$' '{sum+=$NF} END {print "员工平均工资:", sum/NR}' test
  • 执行结果
  • shell加解密aes_sed_07

5.2.3 计算max

  • 实战:计算最高薪资
awk -F '$'  'BEGIN {max_salary=0} {if($NF > max_salary) max_salary=$NF} END { print "最高薪资:", max_salary}'  test
# 简写如下
awk -F '$'  '{if($NF > max_salary) max_salary=$NF} END { print "最高薪资:", max_salary}'  test
# 等价于if语句
awk -F '$'  '$NF > max_salary {max_salary=$NF; max_record=$0 }; END { print "最高薪资:", max_salary, ",完整记录 --", max_record}'  test
  • 执行结果:
  • shell加解密aes_sed_08

5.2.4 计算min

  • 实战:计算最低薪资
  • 注意:
  • 最小值必须指定,求最大值时的1和3两种命令在这里不可行
  • 建议使用第三种计算方法,避免min初始值指定不正确,导致计算出错
# not working的写法
awk -F '$'  '$NF < min_salary {min_salary=$NF;}; END { print "最低薪资:", min_salary}'  test
# 设置一个合理的初始值
awk -F '$'  'BEGIN {min_salary=10000000} {if($NF < min_salary) min_salary=$NF} END { print "最低薪资:",  min_salary}'  test
# 最智能的做法,将第一条记录的值作为初始值
awk -F '$' '{
	if(NR == 1) 
    	{line = $0; min = $NF;}
	else if(NR > 1 && $NF < min)
    	{line = $0; min = $NF;}
    }
	END {print min,"--",line}' test
  • 执行结果:
  • 感谢stackoverflow给的计算min的灵感:awk script for finding smallest value from column