Shell 网络与用户操作
更新时间:2026-08-28。本文是 Shell 编程主题第⑥族:网络通信与用户权限,共 25 个命令。
与 Linux 命令速查第④族、第⑤族 的分工:那边是字典式速查(网络 30 个、用户权限 28 个命令);本文把脚本里最常用的 25 个讲透,重点是怎么做批量操作——批量探测、批量执行、批量建号。
一、HTTP 请求
1.1 curl — 全能 HTTP 客户端
curl 是调试接口的标配,选项虽多但可以按用途分组。控制请求:-X 指定方法(POST/PUT/DELETE,GET 可省略),-d 带请求体(配合 -H 'Content-Type: application/json' 发 JSON),-H 自定义请求头(可多次),-F 上传文件(multipart 表单),-u user:pass 基础认证。--data-urlencode 会自动编码参数,避免手写转义。
控制输出:-s 静默(不显示进度条,脚本里必加),-S 配合 -s 使用——静默但仍显示错误(否则失败时什么都没有,很难排查),-o file 保存到文件,-i 包含响应头,-I 只取响应头(HEAD 请求,看资源元信息用),-v 详细调试(能看到完整的请求和响应头),-w 自定义输出格式。
-w 是 curl 最有价值的特性之一,它能把一次请求的耗时拆开:%{http_code} 状态码、%{time_namelookup} DNS 解析、%{time_connect} TCP 连接、%{time_starttransfer} 首字节(TTFB)、%{time_total} 总计。接口慢的时候,一条命令就能判断慢在 DNS、建连还是服务端处理。
可靠性:--max-time 设总超时(脚本里调用 curl 一定要设,否则对端不响应时脚本会一直挂着,cron 任务堆积能把机器拖垮),--connect-timeout 只设连接超时,--retry N 失败重试,-L 跟随重定向,-k 忽略证书校验(自签证书场景,但注意这不安全)。
curl https://api.example.com # GET
curl -X POST -d '{"k":"v"}' -H 'Content-Type: application/json' URL
curl -H "Authorization: Bearer $TOKEN" URL # 自定义头
curl -o out.html URL # 保存到文件
curl -sS URL # 静默但仍报错(脚本推荐)
curl -I URL # 只看响应头
curl -v URL # 详细调试
curl --max-time 10 --retry 3 URL # 超时 + 重试
curl -L URL # 跟随重定向
curl -k https://self-signed.example # 忽略证书校验
# 拆开看耗时,定位慢在哪一步
curl -w "code:%{http_code} dns:%{time_namelookup} connect:%{time_connect} ttfb:%{time_starttransfer} total:%{time_total}\n" \
-o /dev/null -s URL
# 脚本里判断状态码
code=$(curl -sS -o /dev/null -w '%{http_code}' --max-time 5 URL)
[ "$code" -eq 200 ] && echo OK || echo "异常: $code"1.2 wget — 下载工具
curl 偏接口调试,wget 偏文件下载。-O 指定保存文件名,-c 断点续传(大文件下载中断后继续,不用从头再来),-P 指定下载目录,-r 递归下载(整站镜像),-np 递归时不下载父级目录,-q 静默,--limit-rate 限速(避免占满带宽),-i 从文件读 URL 列表批量下载,--mirror 镜像模式(等价于 -r -N -l inf --no-remove-listing)。
下载单个文件两者都能用,需要断点续传、递归镜像、批量下载时 wget 更省事(一条命令搞定,curl 得写循环)。
wget URL # 下载
wget -O name.tar.gz URL # 指定保存名
wget -c URL # 断点续传
wget -P /data/ URL # 下载到指定目录
wget -i urls.txt # 批量下载(URL 列表文件)
wget --limit-rate=500k URL # 限速
wget -r -np URL # 递归下载整站二、远程登录与传输
2.1 ssh — 远程登录与隧道
ssh 不只是登录,它还能做端口转发和远程执行,几乎是运维的万能通道。远程执行:ssh user@host 'cmd' 执行单条命令后返回,批量操作时必用;多条命令用引号包起来,或者 ssh host 'bash -s' < local_script.sh 把本地脚本送过去执行。
端口转发是它的隐藏大招:-L 8080:localhost:80 host 是本地转发(把远程的 80 端口映射到本地 8080,于是访问 localhost:8080 就等于访问远程的 80,适合访问只对内网开放的服务);-R 2222:localhost:22 host 是反向转发(把本地 22 暴露到远程的 2222,内网穿透常用);-D 1080 起一个 SOCKS5 代理(科学上网或访问内网整段)。
批量执行的关键参数:-o ConnectTimeout=5 设连接超时(批量操作时几乎是必选项,没有它遇到一台不可达的主机就会卡住很久);-o StrictHostKeyChecking=no 跳过首次连接的指纹确认(适合可控内网,公网环境别加,有中间人风险);-o BatchMode=yes 禁止任何交互(密码提示也禁用,适合无人值守)。-J jump target 是跳板机写法(ProxyJump),比把私钥转发到跳板机上安全得多。
ssh user@host # 登录
ssh -p 2222 user@host # 指定端口
ssh -i key.pem user@host # 指定密钥
ssh user@host 'df -h; uptime' # 远程执行多条命令
ssh host 'bash -s' < local.sh # 把本地脚本送过去执行
ssh -o ConnectTimeout=5 -o BatchMode=yes user@host 'cmd' # 脚本批量执行标配
ssh -J jump target # 跳板机
ssh -L 8080:localhost:80 host # 本地端口转发
ssh -R 2222:localhost:22 host # 反向隧道
ssh -D 1080 host # SOCKS5 代理免密登录与密钥配置(生成密钥、分发公钥)见 安全加密与审计速查 与 网络命令速查。生产环境优先配 SSH 免密,避免每次输密码。
2.2 scp — 远程复制
scp 语法接近 cp,只是路径写成 user@host:/path。-r 递归传目录,-P 指定端口(注意是大写 P,ssh 用的是小写 p,这个差异经常让人踩坑),-i 指定密钥,-C 启用压缩(慢网络下能提速,传已压缩的文件反而没必要),-p 保留时间戳和权限,-l 限速(KB/s)。
它的短板是没有进度显示、不支持断点续传——传大文件传到一半断了就得重来。所以大文件或重要传输用 rsync -avP 更稳妥(-P 既显示进度又支持续传)。
scp local.txt user@host:/path/ # 上传
scp user@host:/path/file.txt . # 下载
scp -r dir/ user@host:/path/ # 递归传目录
scp -P 2222 -i key.pem file user@host:/tmp/ # 指定端口和密钥
scp -C bigfile user@host:/tmp/ # 启用压缩传输2.3 rsync — 增量同步
rsync 是"只传变化的部分",这是它与 scp 的本质区别:第二次同步时它只传改动过的文件,且对大文件只传变化的数据块,所以增量备份极快。
常用选项组合:-a 归档模式(保留权限、时间戳、属主、链接等,等价于 -rlptgoD),-v 显示过程,-z 传输时压缩,-h 人类可读,-P 等于 --partial --progress(显示进度且保留半传文件以便续传),--delete 删除目标端那些源端已经没有的文件(让目标严格镜像源,危险但常用,务必先 -n 演练),--exclude 排除模式,--bwlimit 限速(KB/s,避免占满生产带宽),-e 'ssh -p 2222' 指定远程 shell。
-n(--dry-run)是安全使用 --delete 的必备习惯:先 rsync -avn --delete src/ dst/ 看会删什么,确认无误再去掉 n 真正执行。这个参数能救回无数次误删。
--link-dest 做快照备份是进阶技巧:把未变化的文件硬链接到上一份备份,看起来每份都是完整备份,实际只占用变化部分的磁盘空间,配合日期目录能做出高效的增量快照。
rsync -av src/ user@host:/dst/ # 归档 + 增量
rsync -avzP src/ user@host:/dst/ # 压缩 + 进度 + 可续传(推荐)
rsync -avn --delete src/ dst/ # 演练(-n,看会做什么但不执行)
rsync -av --delete src/ dst/ # 真正镜像同步(危险,先演练)
rsync -av --exclude='node_modules' --exclude='.git' src/ dst/ # 排除
rsync -av --bwlimit=1000 src/ host:/dst/ # 限速 1000 KB/s
rsync -av -e 'ssh -p 2222' src/ host:/dst/ # 指定 SSH 端口
# 快照式备份:未变化的文件硬链接到上一份,省空间
rsync -av --delete --link-dest=/backup/latest /data/ /backup/$(date +%F)/三、端口与连接
3.1 ss — 套接字统计
ss 是 netstat 的现代替代品,速度快得多(直接从内核读取而非遍历 /proc)。选项按维度记:-t TCP、-u UDP、-l 只显示监听、-a 全部(含非监听)、-n 数字形式(不解析服务名和域名,加上它输出快很多)、-p 显示占用进程(需 root)、-s 汇总统计。
ss -tlnp 是查"端口被谁占了"的第一命令。ss -s 看连接总数(排查连接数暴涨),ss -tn state established 只看已建立的连接,ss -tan state time-wait | wc -l 统计 TIME_WAIT 数量(高并发短连接服务上容易堆积),ss -i 显示 TCP 内部信息(拥塞窗口、RTT,做网络调优时用)。过滤表达式还支持 dport = :80、src 1.2.3.4 这类。
ss -tlnp # 监听中的 TCP 端口 + 进程(查端口占用第一命令)
ss -tunap # 所有 TCP/UDP 连接
ss -s # 连接数汇总
ss -tn state established # 已建立的连接
ss -tan state time-wait | wc -l # TIME_WAIT 数量
ss -tn 'dport = :80' # 过滤目标端口 80
ss -tnp | grep :8080 # 谁占了 80803.2 netstat
老工具,部分最小化系统可能没装,新系统建议用 ss。选项与 ss 类似(-tlnp、-an),额外有 -i 看网卡统计、-s 看协议栈统计、-r 看路由表。用法基本一致,不再展开。
netstat -tlnp # 监听端口
netstat -an # 全部连接
netstat -s # 协议统计(看丢包、重传)
netstat -i # 网卡统计3.3 ping / traceroute / mtr
ping 走 ICMP 协议测连通性和延迟。-c N 指定发包数(不加的话会一直发,脚本里必须加),-i 设间隔(默认 1 秒,小于 0.2 需 root),-W 设单次超时秒数,-s 设包大小(调大可测 MTU 问题),-q 只显示汇总。
注意很多云厂商和防火墙会禁 ICMP,所以 ping 不通不代表服务不可用——要换成测具体端口的方式(nc -zv 或 curl)。
traceroute 追踪数据包经过的每一跳,-n 不解析域名(输出快得多),-T -p 80 用 TCP SYN 探测(能绕过禁 ICMP 的网络),-m 设最大跳数。mtr 是 ping 与 traceroute 的结合,持续统计每跳的丢包和延迟,定位网络质量问题首选;mtr -rw host 生成报告摘要,适合贴在工单里。
ping -c 4 host # 发 4 个包就停(脚本必加 -c)
ping -c 4 -W 2 host # 每次等 2 秒超时
ping -q -c 10 host # 只显示汇总统计
traceroute -n host # 不解析域名,快
traceroute -T -p 80 host # 用 TCP 探测,绕过禁 ICMP 的网络
mtr host # 实时看每跳质量
mtr -rw host # 生成报告(适合发工单)3.4 nc(netcat)与 telnet
nc 是网络界的瑞士军刀,最常用的是探测端口:nc -zv host 80 测 TCP 端口是否开放(-z 只扫描不发送数据,-v 详细输出),-u 测 UDP,-w N 设超时秒数。它还能起临时服务(nc -l 9000 监听端口做调试)、传文件(nc host 9000 < file)、甚至做简单的端口转发。
telnet 是明文协议,现在基本不用它登录,主要用来手工测端口:telnet host 80 连上后可以手工敲 GET / HTTP/1.0 看服务返回什么,排查"服务起没起"很直观。不过 nc -zv 更适合脚本(有明确的退出码)。
nc -zv host 80 # 测 TCP 端口(脚本用,有退出码)
nc -zvu host 53 # 测 UDP 端口
nc -z -w2 host 1-1000 # 扫端口范围
nc -l 9000 # 监听端口(临时调试服务)
nc host 9000 < file # 传文件
telnet host 80 # 手工连上去敲协议四、网络信息
4.1 ip — 现代网络配置
ip 来自 iproute2 套件,已经全面取代 ifconfig/route/arp 这组老命令(最小化安装的系统里老命令可能根本没有)。它按"对象"组织:ip addr(简写 ip a)看 IP 地址,ip link(ip l)看网卡状态,ip route(ip r)看路由表,ip neigh(ip n)看 ARP 邻居表。
几个特别有用的:ip route get 8.8.8.8 查询"到某个 IP 会走哪条路由"——多网卡机器排查"流量为什么没走我期望的网卡"时,这条命令直接给出答案。ip -s link 显示网卡的流量统计(RX/TX 的包数、错误数、丢包数),看 errors/dropped 是否在涨,是判断物理层故障(网线、光模块、交换机端口)的关键依据。ip -br a 是简洁格式(每行一块网卡,适合快速查看)。
ip addr # 所有网卡的 IP(可简写 ip a)
ip -br a # 简洁格式
ip addr show eth0 # 只看某块网卡
ip link set eth0 up/down # 启停网卡
ip route # 路由表
ip route get 8.8.8.8 # 查到某 IP 走哪条路由(多网卡排障)
ip neigh # ARP 邻居表
ip -s link show eth0 # 流量与错误统计(看丢包)4.2 dig / nslookup / hostname
dig 是功能最全的 DNS 工具。+short 只输出结果(脚本解析用),@8.8.8.8 指定用哪个 DNS 服务器查询(对比不同 DNS 的结果能判断是不是本地 DNS 有问题),+trace 从根服务器逐级追踪解析过程,-x 反向解析(IP 查域名),按记录类型查:A(IPv4)、AAAA(IPv6)、MX(邮件)、CNAME(别名)、TXT(文本,常用于域名验证)、NS(权威服务器)。
DNS 排查的经典流程:dig 域名 看能否解析 → dig @8.8.8.8 域名 换公共 DNS 对比 → 结果不同说明本地 DNS 或劫持有问题 → +trace 看卡在哪一级。
nslookup 更老更简洁,交互和非交互都能用,但输出格式不如 dig 规范。hostname -I 显示本机所有 IP(大写 i),比 ifconfig 快得多;-f 完整域名,-s 短主机名。
dig example.com # 完整解析
dig +short example.com # 只输出 IP(脚本用)
dig @8.8.8.8 example.com # 指定 DNS 服务器
dig +trace example.com # 从根逐级追踪
dig -x 8.8.8.8 # 反向解析
dig example.com MX # 查邮件记录
nslookup example.com # 简版查询
hostname -I # 本机 IP五、用户与权限
5.1 用户管理
useradd 建用户时常用的组合是 -m -s /bin/bash(建家目录 + 指定 shell,不加 -s 的话默认 shell 可能是 /bin/sh,体验很差)。-G 指定附加组,-aG 是追加(usermod -aG docker alice),漏掉 -a 会覆盖用户原有的所有附加组——这是最经典的坑。-r 创建系统用户(无家目录、不能登录,给服务进程用),-u/-g 指定 uid/gid。
passwd 改密码:-l 锁定、-u 解锁、-e 强制下次登录必须改密码(批量建号后必做,否则初始密码长期有效)、-S 查看状态、--stdin 从标准输入读(配合 chpasswd 批量改密)。批量改密用 chpasswd(读 "用户:密码" 格式的输入)。groups 查看用户属组,id 更详细(uid/gid/所有组)。
删除用户 userdel -r 会连同家目录和邮件池一起删(不加 -r 会留下家目录,下次建同名用户会有权限问题)。
useradd -m -s /bin/bash alice # 建用户 + 家目录 + shell
useradd -r -s /sbin/nologin appsvc # 建系统用户(不能登录)
usermod -aG docker alice # 追加到附加组(注意 -a 不能漏)
usermod -L alice # 锁定账号
userdel -r alice # 删用户 + 家目录
passwd -e alice # 强制下次登录改密码
echo 'alice:NewPass123' | chpasswd # 批量改密
groups alice # 查看属组5.2 sudo 与 su
两者的分工要分清:sudo 是"以别人的身份做一件事"(用自己的密码,需要被授权),su 是"变成另一个人"(要知道对方的密码)。生产环境几乎都推荐 sudo——不用共享 root 密码,且每条 sudo 命令都会留下审计记录。
sudo 常用:-u user 指定以谁的身份(默认 root),-i 进入登录 shell(带完整的 root 环境),-l 查看自己被授予了哪些权限(不知道能不能 sudo 时先查这个),-k 清空密码缓存(下次 sudo 要重新输密码),-v 延长缓存有效期,sudo !! 用 sudo 重跑上一条命令(忘了加 sudo 时的救星)。
su - alice 的横杠很重要:它表示"载入目标用户的完整环境"(不加载入的话,环境变量还是原来用户的,可能出现命令找不到之类的问题)。
改 sudo 配置必须用 visudo,它会做语法检查;直接编辑 /etc/sudoers 写错的话,整个系统的 sudo 就瘫痪了,只能进单用户模式抢修。新增授权建议写在 /etc/sudoers.d/ 下的独立文件里(升级系统时主文件可能被覆盖,独立目录不会)。
sudo cmd # 以 root 执行
sudo -u www cmd # 以 www 用户执行
sudo -i # 进入 root 登录 shell
sudo -l # 查看自己的权限
sudo !! # 用 sudo 重跑上一条命令
sudoedit /etc/nginx/nginx.conf # 安全编辑特权文件(保留自己的编辑器配置)
su - alice # 切换用户并载入其环境
visudo # 安全编辑 sudoers(会校验语法)
visudo -f /etc/sudoers.d/alice # 编辑独立授权文件(推荐)5.3 文件权限
chmod、chown、umask 的完整参数(数字法、符号法、特殊位 SUID/SGID/sticky)已在 文件与目录命令详解 中讲透,这里只列最常用的三条:
chmod 755 script.sh # rwxr-xr-x
chmod +x script.sh # 加执行位(脚本写完必做)
chown alice:dev file # 改属主属组
umask 022 # 新文件 644、新目录 755更精细的按用户授权用 ACL(setfacl/getfacl),防篡改属性用 chattr,见 Linux 命令速查第⑤族。
六、脚本实战:批量操作
网络和用户管理在脚本里最常见的形态就是"对一批机器或一批人做同样的事"。下面几个模式基本能覆盖日常运维需求。
6.1 批量连通性检测
# 串行版
while read -r host; do
if nc -z -w 2 "$host" 22 2>/dev/null; then
echo "OK $host:22"
else
echo "FAIL $host:22"
fi
done < hosts.txt
# 并发版(用 xargs -P 提速)
xargs -a hosts.txt -P 10 -I{} sh -c 'nc -z -w 2 {} 22 && echo "OK {}" || echo "FAIL {}"'串行探测 100 台主机,每台超时 2 秒,最坏要等 200 秒。xargs -P 10 开 10 个并发,时间直接除以 10。注意并发数别开太大,否则可能耗尽本地端口或把对端打爆。
6.2 接口健康检查
check_api() {
local url=$1
curl -sS -o /dev/null -w "%{http_code} %{time_total}\n" --max-time 5 "$url" 2>&1
}
check_api "https://api.example.com/health"--max-time 在脚本里是必选项:没有它,对端不响应时脚本会一直挂着,cron 任务堆积起来能把机器拖垮。
6.3 SSH 批量执行
while read -r host; do
echo "=== $host ==="
ssh -o ConnectTimeout=5 -o BatchMode=yes "user@$host" \
'uptime; df -h / | tail -1' 2>&1
done < hosts.txtConnectTimeout 在批量执行时几乎是必选项;BatchMode=yes 禁止任何交互(包括密码提示),确保脚本不会因为等待输入而卡死。
6.4 批量建号与授权
#!/usr/bin/env bash
set -euo pipefail
# users.txt 每行格式: 用户名:组名
while IFS=: read -r user group; do
[ -z "${user:-}" ] && continue
if id "$user" &>/dev/null; then
echo "已存在,跳过: $user"
continue
fi
groupadd -f "$group"
useradd -m -s /bin/bash -G "$group" "$user"
passwd=$(openssl rand -base64 12)
echo "$user:$passwd" | chpasswd
passwd -e "$user" # 强制首次登录改密
echo "已创建: $user (组: $group) 初始密码: $passwd"
done < users.txt批量建号两个要点:一是幂等(先 id 判断,已存在就跳过,重跑不出错),二是强制密码过期(passwd -e),否则初始密码会以明文长期留在脚本输出或日志里。生产环境更推荐直接分发 SSH 公钥、禁用密码登录。
6.5 rsync 增量备份
#!/usr/bin/env bash
SRC=/data/app/
DST=/backup/app/
DATE=$(date +%F)
rsync -av --delete --link-dest="$DST/latest" "$SRC" "$DST/$DATE/"
rm -f "$DST/latest"
ln -s "$DATE" "$DST/latest"
# 清理 7 天前的备份
find "$DST" -maxdepth 1 -type d -mtime +7 -exec rm -rf {} +--link-dest 是快照备份的精髓:未变化的文件硬链接到上一份,看起来是完整的一份,实际磁盘只存了变化的部分。
七、与主线衔接
curl -w耗时拆分、ss -tlnp端口排查,是 tools/network 的脚本化入口。- 更完整的网络命令清单(iperf3、wrk、tshark、tc 等)见 网络进阶与压测速查。
sudo提权与权限模型,衔接 进程与系统命令 与 安全加密与审计。- 用户权限的完整参数见 Linux 命令速查第⑤族。
一句话总结
网络用户操作 = 请求(curl/wget)+ 远程(ssh/scp/rsync)+ 端口(ss/nc)+ 配置(ip/dig)+ 权限(useradd/sudo);脚本里的四条经验——调 curl 必设 --max-time,批量探测用 xargs -P 并发,批量 ssh 加 ConnectTimeout 和 BatchMode,rsync --delete 前先 -n 演练。