30个经典shell脚本(下)

匿名 (未验证) 提交于 2019-12-03 00:05:01
本文目录

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;)printf i"x"n"="i*n" ";print ""}}'

方法2:

for ((i=1;i<=9;i++)); do

for ((j=1;j<=i;j++)); do

result=$(($i*$j))

echo -n "$j*$i=$result "

done

echo

done

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

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

命令格式:getopts optstring name [arg]

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

脚本位置参数会与optstring中的单个字母逐个匹配,如果匹配到就赋值给name,否则赋值name为问号;

optstring中单个字母是一个选项,如果字母后面加冒号,表示该选项后面带参数,参数值并会赋值给OPTARG变量;

optstring中第一个是冒号,表示屏蔽系统错误(test.sh: illegal option -- h);

允许把选项放一起,例如-ab

 

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

#!/bin/bash

while getopts :f:n: option; do

case $option in

f)

FILE=$OPTARG

[ ! -f $FILE ] && echo "$FILE File not exist!" && exit

;;

n)

sed -n "${OPTARG}p" $FILE

;;

?)

echo "Usage: $0 -f -n "

echo "-f, --file specified file"

echo "-n, --line-number print specified line"

exit 1

;;

esac

done

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!