shell4(批量修改文件名、Expect、网段ip测试)

1、从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
复制代码

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

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

方法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]})

3、批量修改文件名

# 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

4、统计当前目录中以.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

5、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脚本独立出来

登录脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#!/bin/bash
 
password=xxxxxx
 
# 安装 expect 自动捕获工具
yum -y install expect 1>/dev/null 2>&1
 
# 自动生成密钥
key_generate() {
    expect -c "
        set timeout -1;
        spawn ssh-keygen -t ed25519;
        expect {
            {Enter file in which to save the key*} {send -- \r;exp_continue}
            {Enter passphrase*} {send -- \r;exp_continue}
            {Enter same passphrase again:} {send -- \r;exp_continue}
            {Overwrite (y/n)*} {send -- n\r;exp_continue}
            eof {exit 0;}
        };"
    ssh-add
}
 
# 将密钥发送至需要免密登录的服务器
auto_ssh_copy_id () {
    expect -c "
        set timeout -1;
        spawn ssh-copy-id -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null $1;
        expect {
            {*password:} {send -- $2\r; exp_continue;}
            eof {exit 0;}
        };"
}
 
key_generate
 
#echo > /root/.ssh/known_hosts
 
# 根据 /etc/hosts 文件中的 IP 地址和预定的密码设置免密登录
ips=$(cat /etc/hosts | grep -v "::" | grep -v "127.0.0.1" | cut -f 1)
for ip in $ips
do
    auto_ssh_copy_id $ip $password
done

补充:Ed25519 

  1. Ed25519 算法

    • 安全性:Ed25519 是一种基于椭圆曲线密码学(Elliptic Curve Cryptography, ECC)的密钥生成算法,提供高效的加密安全性。与传统的 RSA 算法相比,在相同的安全级别下,Ed25519 的密钥长度更短。
    • 性能:生成和验证 Ed25519 密钥比传统算法(如 RSA 或 DSA)更快,特别是在低功耗设备上表现更佳。
  2. 生成过程

    • 当你运行 ssh-keygen -t ed25519 时,程序会提示你输入文件名以保存密钥。如果你直接按 Enter,它会将密钥保存在默认位置(通常是 ~/.ssh/id_ed25519)。
    • 接着,系统会询问你输入一个密码短语(passphrase),用于进一步保护私钥。你可以选择留空,但建议设置一个密码来增强安全性。
  3. 生成的文件

    • 生成后,会得到两个文件:
      • ~/.ssh/id_ed25519 —— 私钥。
      • ~/.ssh/id_ed25519.pub —— 公钥。可以安全地分享给其他人,或将其添加到 SSH 服务器的 ~/.ssh/authorized_keys 文件中,以实现无密码 SSH 登录。

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

复制代码
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
复制代码

9、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
复制代码

10、测试 192.168.4.0/24 整个网段主机的开关机状态

多进程版

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/bin/bash
# 编写脚本测试 192.168.4.0/24 整个网段中哪些主机处于开机状态,哪些主机处于关机
# 状态(多进程版)
  
#定义一个函数,ping 某一台主机,并检测主机的存活状态
myping(){
ping ‐c 2 ‐i 0.3 ‐W 1 $1  &>/dev/null
if  [ $? -eq 0 ];then
    echo "$1 is up"
else
    echo "$1 is down"
fi
}
for i in {1..254}
do
    myping 192.168.4.$i &
done
# 使用&符号,将执行的函数放入后台执行
# 这样做的好处是不需要等待ping第一台主机的回应,就可以继续并发ping第二台主机,依次类推

在线和离线主机输出到文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#!/bin/bash
 
ping_success_status() {
if ping -c 1 $IP >> /dev/null; then
echo "$IP is on" >> /root/success-host.txt
continue
fi
}
 
success=/root/success-host.txt
failure=/root/failure-host.txt
 
rm -rf $success
rm -rf $failure
 
if [[ ! -f  $success ]];then
touch  /root/success-host.txt  && chmod 777 /root/success-host.txt
echo "$success 文件创建成功"
else
echo "$success 文件已经存在"
fi
 
if [[ ! -f  $failure ]];then
touch  /root/failure-host.txt && chmod 777 /root/failure-host.txt
echo "$failure 文件创建成功"
else
echo "$failure 文件已经存在"
fi
 
for IP in `echo 10.1.1.{1..254}`
do
{ ping_success_status
echo "$IP  is off!" >> /root/failure-host.txt
} &
done
wait
 
echo "在线主机数如下:" && cat /root/success-host.txt  | wc -l
#cat /root/success-host.txt
 
echo "离线主机数如下:" && cat /root/failure-host.txt  | wc -l
#cat /root/failure-host.txt

while版

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/bin/bash
# 编写脚本测试 192.168.4.0/24 整个网段中哪些主机处于开机状态,哪些主机处于关机
# 状态(while 版本)
i=1
while [ $i -le 254 ]
do
    ping ‐c 2 ‐i 0.3 ‐W 1 192.168.4.$i  &>/dev/null
    if  [ $? -eq 0 ];then
        echo "192.168.4.$i is up"
    else
        echo  "192.168.4.$i is down"
    fi
    let i++
done

 

posted @   凡人半睁眼  阅读(447)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具
· Manus的开源复刻OpenManus初探

阅读目录(Content)

此页目录为空

点击右上角即可分享
微信分享提示