挚爱咖啡
作者挚爱咖啡联盟成员·2019-07-16 11:06
系统架构师·某银行

30个Linux Shell脚本经典案例(下)

字数 5021阅读 5390评论 0赞 7

上一篇: **[30个Linux Shell脚本经典案例(中)]

本章目录

21、从FTP服务器下载文件

22、连续输入5个100以内的数字,统计和、最小和最大

23、将结果分别赋值给变量

24、批量修改文件名

25、统计当前目录中以.html结尾的文件总大

26、扫描主机端口状态

27、Expect实现SSH免交互执行命令

28、批量修改服务器用户密码

29、打印乘法口诀

30、getopts工具完善脚本命令行参数

---------------------------

21、从FTP服务器下载文件

!/bin/bash

if [ $# -ne 1 ]; then

echo "Usage: $0 filename"  

fi
dir=$(dirname $1)
file=$(basename $1)
ftp -n -v << EOF # -n 自动登录
open 192.168.1.10 # ftp服务器
user admin password
binary # 设置ftp传输模式为二进制,避免MD5值不同或.tar.gz压缩包格式错误
cd $dir
get "$file"
EOF

22、连续输入5个100以内的数字,统计和、最小和最大

!/bin/bash

COUNT=1
SUM=0
MIN=0
MAX=100
while [ $COUNT -le 5 ]; do

read -p "请输入1-10个整数:" INT  
if [[ ! $INT =~ ^[0-9]+$ ]]; then  
    echo "输入必须是整数!"  
    exit 1  
elif [[ $INT -gt 100 ]]; then  
    echo "输入必须是100以内!"  
    exit 1  
fi  
SUM=$(($SUM+$INT))  
[ $MIN -lt $INT ] && MIN=$INT  
[ $MAX -gt $INT ] && MAX=$INT  
let COUNT++  

done
echo "SUM: $SUM"
echo "MIN: $MIN"
echo "MAX: $MAX"

23、将结果分别赋值给变量

应用场景:希望将执行结果或者位置参数赋值给变量,以便后续使用。

方法1:

for i in $(echo "4 5 6"); do
eval a$i=$i
done
echo $a4 $a5 $a6

方法2:将位置参数192.168.1.1{1,2}拆分为到每个变量

num=0
for i in $(eval echo $*);do #eval将{1,2}分解为1 2
let num+=1
eval node${num}="$i"
done
echo $node1 $node2 $node3

bash a.sh 192.168.1.1{1,2}

192.168.1.11 192.168.1.12

方法3:

arr=(4 5 6)
INDEX1=$(echo ${arr[0]})
INDEX2=$(echo ${arr[1]})
INDEX3=$(echo ${arr[2]})

24、批量修改文件名

示例:

touch article_{1..3}.html

ls

article_1.html article_2.html article_3.html

目的:把article改为bbs

方法1:

for file in $(ls *html); do
mv $file bbs_${file#*_}

mv $file $(echo $file |sed -r 's/.(_.)/bbs\1/')

mv $file $(echo $file |echo bbs_$(cut -d_ -f2)

done

方法2:

for file in $(find . -maxdepth 1 -name "*html"); do
mv $file bbs_${file#*_}
done

方法3:

rename article bbs *.html

25、统计当前目录中以.html结尾的文件总大

方法1:

find . -name "*.html" -exec du -k {} \; |awk '{sum+=$1}END{print sum}'

方法2:

for size in $(ls -l *.html |awk '{print $5}'); do
sum=$(($sum+$size))
done
echo $sum

26、扫描主机端口状态

!/bin/bash

HOST=$1
PORT="22 25 80 8080"
for PORT in $PORT; do

if echo &>/dev/null > /dev/tcp/$HOST/$PORT; then  
    echo "$PORT open"  
else  
    echo "$PORT close"  
fi  

done

27、Expect实现SSH免交互执行命令

Expect是一个自动交互式应用程序的工具,如telnet,ftp,passwd等。

需先安装expect软件包。

方法1:EOF标准输出作为expect标准输入

!/bin/bash

USER=root
PASS=123.com
IP=192.168.1.120
expect << EOF
set timeout 30
spawn ssh $USER@$IP
expect {

"(yes/no)" {send "yes\\r"; exp_continue}  
"password:" {send "$PASS\\r"}  

}
expect "$USER@*" {send "$1\r"}
expect "$USER@*" {send "exit\r"}
expect eof
EOF

方法2:

!/bin/bash

USER=root
PASS=123.com
IP=192.168.1.120
expect -c "

spawn ssh $USER@$IP  
expect {  
    \\"(yes/no)\\" {send \\"yes\\r\\"; exp_continue}  
    \\"password:\\" {send \\"$PASS\\r\\"; exp_continue}  
    \\"$USER@*\\" {send \\"df -h\\r exit\\r\\"; exp_continue}  
}"

方法3:将expect脚本独立出来

登录脚本:

cat login.exp

!/usr/bin/expect

set ip [lindex $argv 0]
set user [lindex $argv 1]
set passwd [lindex $argv 2]
set cmd [lindex $argv 3]
if { $argc != 4 } {
puts "Usage: expect login.exp ip user passwd"
exit 1
}
set timeout 30
spawn ssh $user@$ip
expect {

"(yes/no)" {send "yes\\r"; exp_continue}  
"password:" {send "$passwd\\r"}  

}
expect "$user@*" {send "$cmd\r"}
expect "$user@*" {send "exit\r"}
expect eof

执行 命令脚本:写个循环可以批量操作多台服务器

!/bin/bash

HOST_INFO=user_info.txt
for ip in $(awk '{print $1}' $HOST_INFO)
do

user=$(awk -v I="$ip" 'I==$1{print $2}' $HOST_INFO)  
pass=$(awk -v I="$ip" 'I==$1{print $3}' $HOST_INFO)  
expect login.exp $ip $user $pass $1  

done

Linux主机SSH连接信息:

cat user_info.txt

192.168.1.120 root 123456

28、批量修改服务器用户密码

Linux主机SSH连接信息:旧密码

cat old_pass.txt

192.168.18.217 root 123456 22
192.168.18.218 root 123456 22

内容格式:IP User Password Port

SSH远程修改密码脚本:新密码随机生成

!/bin/bash

OLD_INFO=old_pass.txt
NEW_INFO=new_pass.txt
for IP in $(awk '/^[^#]/{print $1}' $OLD_INFO); do

USER=$(awk -v I=$IP 'I==$1{print $2}' $OLD_INFO)  
PASS=$(awk -v I=$IP 'I==$1{print $3}' $OLD_INFO)  
PORT=$(awk -v I=$IP 'I==$1{print $4}' $OLD_INFO)  
NEW_PASS=$(mkpasswd -l 8)  # 随机密码  
echo "$IP   $USER   $NEW_PASS   $PORT" >> $NEW_INFO  
expect -c "  
spawn ssh -p$PORT $USER@$IP  
set timeout 2  
expect {  
    \\"(yes/no)\\" {send \\"yes\\r\\";exp_continue}  
    \\"password:\\" {send \\"$PASS\\r\\";exp_continue}  
    \\"$USER@*\\" {send \\"echo \\'$NEW_PASS\\' |passwd --stdin $USER\\r exit\\r\\";exp_continue}  
}"  

done

生成 新密码文件:

cat new_pass.txt

192.168.18.217 root n8wX3mU% 22
192.168.18.218 root c87;ZnnL 22

29、打印乘法口诀

方法1:

awk 'BEGIN{for(n=0;n++<9;){for(i=0;i++ -n "

echo "-f, --file specified file"
echo "-n, --line-number print specified line"
exit 1
;;
esac
done

30、getopts工具完善脚本命令行参数

getopts是一个解析脚本选项参数的工具。

命令格式: getopts optstring name [arg]

初次使用你要注意这几点:

  • 脚本位置参数会与optstring中的单个字母逐个匹配,如果匹配到就赋值给name,否则赋值name为问号;
  • optstring中单个字母是一个选项,如果字母后面加冒号,表示该选项后面带参数,参数值并会赋值给OPTARG变量;
  • optstring中第一个是冒号,表示屏蔽系统错误(test.sh: illegal option -- h);
  • 允许把选项放一起,例如-ab

    下面写一个打印文件指定行的简单例子,引导你思路:

根据工作经验总结的30个Shell脚本案例至此完结,都还是比较实用的,面试笔试题也经常会出。希望朋友们多动手练一练,让你的Shell功底上升一个段位!

本文作者: 李振良

如果觉得我的文章对您有用,请点赞。您的支持将鼓励我继续创作!

7

添加新评论0 条评论

Ctrl+Enter 发表

作者其他文章

相关文章

相关问题

相关资料

X社区推广