/dev/null2>&1...">
当前位置:首页 > 技术 > 正文内容

Shell脚本实用技巧:文件重命名、Expect自动化与网络扫描

访客 技术 2026年9月15日 12

从FTP服务器下载文件

以下脚本演示如何无交互方式从FTP服务器下载指定文件:

#!/bin/bash
[ $# -ne 1 ] && { echo "用法:$0 文件路径"; exit 1; }

dir=$(dirname "$1")
 fname=$(basename "$1")

ftp -n -v << EOF
open 192.168.1.10
user admin password
binary
cd "$dir"
get "$fname"
EOF

动态变量赋值方案

场景一:将字符串"4 5 6"映射为变量a4、a5、a6:

for val in 4 5 6; do
  eval "var_$val=$val"
done
echo $var_4 $var_5 $var_6

场景二:解析参数如"192.168.1.1{1,2}"为独立变量:

num=0
for ip in $(eval echo "$@"); do
  ((num++))
  eval "host_$num=$ip"
done
echo $host_1 $host_2

场景三:使用数组提取元素:

vals=(4 5 6)
var1=${vals[0]}
var2=${vals[1]}
var3=${vals[2]}

批量重命名HTML文件

现有文件:article_1.html、article_2.html、article_3.html → 改为bbs_*.html

方式一(基础for循环):

for file in *.html; do
  newname="bbs_${file#*_}"
  mv "$file" "$newname"
done

方式二(find查找):

find . -maxdepth 1 -name "*.html" -exec sh -c '
  for f; do
    mv "$f" "bbs_${f#*_}"
  done
' _ {} +

方式三(rename命令):

rename 's/article_/bbs_/' *.html

统计HTML文件总大小

方法一(find + awk):

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

方法二(ls + for循环):

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

Expect自动化SSH交互

Expect工具常用于自动应答交互式程序(如SSH),需提前安装:

方式一(内联Expect脚本):

user=root
passwd=123.com
host=192.168.1.120

expect << EOF
set timeout 30
spawn ssh $user@$host
expect {
  "(yes/no)" { send "yes\r"; exp_continue }
  "password:" { send "$passwd\r" }
}
expect "*@*" { send "$1\r"; exp_continue }
expect "*@*" { send "exit\r" }
expect eof
EOF

方式二(expect -c单行调用):

expect -c "
spawn ssh root@192.168.1.120
expect {
  \"(yes/no)\" {send \"yes\\r\"; exp_continue}
  \"password:\" {send \"123.com\\r\"; exp_continue}
  \"root@*\" {send \"df -h\\rexit\\r\"; exp_continue}
}"

方式三(独立Expect脚本):自动化分发SSH密钥(Ed25519算法)

#!/bin/bash
PASSWD="xxxxxx"
SSH_USER="root"

install_expect() {
  yum -y install expect >/dev/null 2>&1 || apt-get install -y expect >/dev/null 2>&1
}

gen_key() {
  expect -c "
    set timeout -1
    spawn ssh-keygen -t ed25519
    expect {
      *\"Enter file*\" { send \"\\r\"; exp_continue }
      *\"Enter passphrase*\" { send \"\\r\"; exp_continue }
      *\"repeat*\" { send \"\\r\"; exp_continue }
      eof { exit 0 }
    }"
  ssh-add
}

copy_key() {
  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 }
    }"
}

install_expect
gen_key

for h in $(grep -v '^127.0.0\|^::' /etc/hosts | awk '{print $1}'); do
  copy_key $h $PASSWD
done

批量更新服务器密钥

原始凭证文件(old_pass.txt)格式:IP 用户名 旧密码 端口(每行一项):

192.168.18.217 root 123456 22
192.168.18.218 root 123456 22

自动修改密码脚本:

OLD_INFO="old_pass.txt"
NEW_INFO="new_pass.txt"
> "$NEW_INFO"

while read ip user passwd port; do
  [ -z "$ip" ] && continue
  newpass=$(mkpasswd -l 8)
  echo "$ip $user $newpass $port" >> "$NEW_INFO"

  expect -c "
    spawn ssh -p $port $user@$ip
    set timeout 2
    expect {
      \"(yes/no)\" { send \"yes\\r\"; exp_continue }
      \"password:\" { send \"$passwd\\r\"; exp_continue }
      \"$user@*\" { send \"echo '$newpass' | passwd --stdin $user\\rexit\\r\"; exp_continue }
    }"
done < "$OLD_INFO"

getopts解析命令行参数

示例:指定文件和行号打印内容:

#!/bin/bash
while getopts :f:n: opt; do
  case $opt in
    f) FILE="$OPTARG"; [ ! -f "$FILE" ] && { echo "文件不存在"; exit 1; };;
    n) sed -n "${OPTARG}p" "$FILE";;
    ?) echo "用法:$0 -f 文件 -n 行号"; exit 1;;
  esac
done

并发测试192.168.4.0/24网段存活主机

多进程方案(后台并行ping):

check_host() {
  ping -c 2 -i 0.3 -W 1 "$1" &>/dev/null
  echo "$1 is $([ $? -eq 0 ] && echo up || echo down)"
}

for i in {1..254}; do
  check_host "192.168.4.$i" &
done
wait

结果输出到文件(含去重处理):

success_file="/root/online-hosts.txt"
failure_file="/root/offline-hosts.txt"
> "$success_file"; > "$failure_file"

for ip in 10.1.1.{1..254}; do
  {
    if ping -c 1 "$ip" &>/dev/null; then
      echo "$ip is online" >> "$success_file"
    else
      echo "$ip is offline" >> "$failure_file"
    fi
  } &
done
wait

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
  ((i++))
done

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。