「速通Shell」常用命令(下)—— 归档、权限与进阶工具

前两篇讲了文件与文本、进程与网络,把 shell 编程日常打交道的高频命令过了一大半。这一篇是这个系列的最后一部分,讲剩下的三块内容:归档压缩、权限用户、还有一些进阶工具。

这三块命令的特点是"用得不多但每次都要查",归档一年可能就用几次,权限脚本天天用但参数容易忘,xargs 和 cron 这种工具型命令用好了能省很多事。读完这一篇,三篇常用命令系列就完整了。

一、归档与压缩

归档和压缩在 shell 里是两个动作:归档是把多个文件合成一个(用 tar),压缩是把单个文件变小(用 gzip、xz 等)。日常我们用 tar 同时做这两件事------tar 本身不压缩,但可以调用 gzip 或 xz 一起做。

1.1 tar:归档

tar 是 tape archive 的缩写,源自磁带备份时代。现代 tar 的核心用途是把目录打包成一个文件。

bash 复制代码
# 打包
tar -cf archive.tar dir/
​
# 解包
tar -xf archive.tar
​
# 查看内容
tar -tf archive.tar

这几个是最基础的用法。但日常我们更常用"打包+压缩":

bash 复制代码
# 打包并用 gzip 压缩
tar -czf archive.tar.gz dir/
​
# 打包并用 xz 压缩(更小但更慢)
tar -cJf archive.tar.xz dir/
​
# 打包并用 bzip2 压缩
tar -cjf archive.tar.bz2 dir/
​
# 解压(tar 自动识别压缩格式)
tar -xzf archive.tar.gz
tar -xJf archive.tar.xz
tar -xjf archive.tar.bz2

几个常用选项

  • -c:创建归档
  • -x:解压归档
  • -t:列出归档内容
  • -v:详细输出(列出处理的文件)
  • -f:指定文件名(必须紧跟文件名,比如 -f archive.tar)
  • -C:解压到指定目录
  • --exclude:排除某些文件
  • -z:gzip 压缩
  • -j:bzip2 压缩
  • -J:xz 压缩
  • -p:保留权限

几个实战组合

bash 复制代码
# 打包并排除某些文件
tar -czf backup.tar.gz --exclude='*.log' --exclude='tmp/' /var/data/
​
# 打包并显示进度
tar -czf - dir/ | pv > archive.tar.gz
​
# 解压到指定目录
tar -xzf archive.tar.gz -C /opt/
​
# 解压单个文件(不解压整个归档)
tar -xzf archive.tar.gz path/inside/file.txt
​
# 追加文件到现有 tar(不常用)
tar -rf archive.tar newfile.txt

tar 的一个细节-f 必须紧跟文件名,不能分开写 -f file.tar-zcvf-zcfv 等价,但 -zvfc 是不行的。

1.2 各种压缩格式的取舍

python 复制代码
# gzip:默认选择,平衡速度和压缩率
gzip file.txt          # 压缩(会删除原文件)
gunzip file.txt.gz     # 解压
​
# bzip2:压缩率比 gzip 高,速度慢
bzip2 file.txt
bunzip2 file.txt.bz2
​
# xz:压缩率最高,速度最慢
xz file.txt
unxz file.txt.xz
​
# zip:跨平台(Windows 也认),压缩率一般
zip -r archive.zip dir/
unzip archive.zip

压缩格式的取舍:

  • gzip:最快,压缩率中等,日常首选,.tar.gz.tgz 后缀。
  • bzip2:比 gzip 小一点,比 gzip 慢一点,.tar.bz2
  • xz:压缩率最高,但慢得多。适合一次压缩、多次解压的场景(比如发布包)。
  • zip:跨平台(Windows、macOS 都认),但 shell 脚本里 tar 更主流。

建议日常备份、传输用 gzip,需要发版本包、长期归档用 xz,需要跟 Windows 共享用 zip。

1.3 7z:高压缩率

7z 是 7-Zip 的命令行版本,压缩率比 xz 还高一点。

bash 复制代码
# 安装
apt install p7zip-full    # Debian/Ubuntu
yum install p7zip         # CentOS/RHEL
​
# 压缩
7z a archive.7z dir/
​
# 解压
7z x archive.7z

7z 适合"必须最小"的场景(嵌入式系统、网络传输受限),日常用得少。

二、权限与用户

权限是 Linux 系统的基础设施。shell 脚本里打交道最多的权限相关命令是 chmod、chown、umask、sudo。这一节把这几个讲清楚。

2.1 文件权限的基础

在讲命令之前,先快速回顾 Linux 文件权限。ls -l 的第一列是权限位:

sql 复制代码
-rw-r--r-- 1 user group 1024 Jan 1 12:00 file.txt
drwxr-xr-x 2 user group 4096 Jan 1 12:00 dir/

权限位分四组解读:

  • 第 1 位:文件类型(- 普通文件、d 目录、l 链接)
  • 第 2-4 位:所有者(user)权限
  • 第 5-7 位:所属组(group)权限
  • 第 8-10 位:其他人(other)权限

每组三位分别是:读 r(4)、写 w(2)、执行 x(1)。数字表示是把三个权限位的值加起来。

2.2 chmod:改权限

bash 复制代码
# 数字模式
chmod 755 file.sh        # rwxr-xr-x
chmod 644 file.txt       # rw-r--r--
chmod 600 secret.key     # rw-------
chmod 700 private/       # rwx------
​
# 符号模式
chmod u+x file.sh        # 所有者加执行权限
chmod g-w file.txt       # 所属组去掉写权限
chmod o=r file.txt       # 其他人只设读权限
chmod a+r file.txt       # 所有人都加读权限
chmod +x script.sh       # 简写:所有人加执行权限

几个常见权限:

  • 644:文件默认权限,所有者可读写,其他人只读。
  • 755:可执行文件或目录的默认权限,所有人可执行(对目录意味着可进入)。
  • 600:私有文件(如密钥),只有所有者能读写。
  • 700:私有目录(如 .ssh),只有所有者能进入。

批量改权限

bash 复制代码
# 把目录下所有 .sh 加上可执行
find . -name "*.sh" -exec chmod +x {} ;
​
# 递归设目录为 755,文件为 644(很常见的部署场景)
find /opt/myapp -type d -exec chmod 755 {} ;
find /opt/myapp -type f -exec chmod 644 {} ;

2.3 chown / chgrp:改所有者和组

bash 复制代码
# 改所有者
chown alice file.txt
​
# 改所有者和组
chown alice:developers file.txt
​
# 改组(只改组)
chgrp developers file.txt
​
# 递归改
chown -R alice:developers /opt/myapp/

chown 只能由 root 执行,普通用户不能改自己文件的所有者,组的话要看用户是不是组成员。

2.4 umask:默认权限

umask 是"用户文件创建掩码"------它决定新创建的文件和目录的默认权限。

bash 复制代码
# 查看当前 umask
umask
# 输出:0022
​
# 设置 umask
umask 022

umask 的算法:默认权限减去 umask。

  • 文件默认权限是 666
  • 目录默认权限是 777
  • 实际权限 = 默认权限 - umask

例如 umask 022 时:

  • 新文件:666 - 022 = 644
  • 新目录:777 - 022 = 755

建议:服务器上 umask 通常是 0022,安全场景用 0077(只有自己能看)。脚本里如果要严格控制文件权限,可以临时改 umask:

bash 复制代码
old_umask=$(umask)
umask 077
# 接下来创建的文件都是 600 权限
touch secret.key
umask "$old_umask"

2.5 sudo / su:提权

sudo 让普通用户以 root(或别的用户)身份执行命令。

bash 复制代码
# 以 root 身份执行
sudo apt update
​
# 以别的用户身份执行
sudo -u alice whoami
​
# 切换到 root shell
sudo -i
sudo su -
​
# 编辑文件(需要权限时)
sudo vim /etc/nginx/nginx.conf
​
# 列出当前用户能 sudo 的命令
sudo -l

sudo 使用时需要注意安全

  • 永远不要 sudo chmod 777------这是给所有人完全权限,生产环境出事故的常见原因
  • sudo 不是"万能钥匙"------它受 /etc/sudoers 配置限制,用户必须有权限才能 sudo
  • 远程操作重要服务时,避免直接 sudo,改用专门的运维账号

su 是 switch user 的缩写,跟 sudo 区别是:

  • sudo 是"借权限",输入自己的密码
  • su 是"切换身份",需要目标用户的密码(root 用户切换不需要)

日常推荐用 sudo------可以审计、可配置、不需要共享 root 密码。

2.6 id / groups:查身份

bash 复制代码
# 当前用户信息
id
# 输出:uid=1000(alice) gid=1000(alice) groups=1000(alice),27(sudo)
​
# 只看 UID
id -u
​
# 只看组
id -g
​
# 列出所有组
groups

id 在脚本里很常用------判断当前是不是 root:

bash 复制代码
if [ "$(id -u)" -ne 0 ]; then
    echo "请用 root 运行此脚本" >&2
    exit 1
fi

三、进阶工具

最后这一组是工具型命令,它们本身不直接做事,但能放大其他命令的能力。

3.1 xargs:把 stdin 变成参数

xargs 是 shell 里最容易被低估的命令之一。它解决"命令参数太长怎么办"和"组合命令"两个问题。

bash 复制代码
# 最常见用法:find + xargs + 命令
find . -name "*.log" | xargs rm
​
# 等价但更安全(处理文件名含空格的情况)
find . -name "*.log" -print0 | xargs -0 rm

-print0-0 配合用 null 字符分隔------这是处理"文件名含空格"的安全模式。

bash 复制代码
# 每个文件执行一次命令
echo "file1 file2 file3" | xargs -n 1 cp -- /tmp/
​
# 并行执行
find . -name "*.jpg" | xargs -P 4 -I {} convert {} -resize 50% {}.small.jpg

-P N 是"用 N 个进程并行执行"------这是 xargs 做并发任务的关键。

bash 复制代码
# 用占位符指定参数位置
find . -name "*.sh" | xargs -I {} chmod +x {}
​
# 处理包含特殊字符的输入
echo "name with spaces" | xargs -d '\n' touch

xargs 跟 find -exec 的取舍:

  • xargs 性能更好(一次调用处理多个文件),但要小心文件名特殊字符
  • -exec 更安全(每个文件单独调用),但慢

默认用 find ... -print0 | xargs -0 ... 模式,又快又安全。

3.2 tee:一箭双雕

tee 把 stdin 同时输出到 stdout 和文件,既能在屏幕看到,又能保存到日志。

bash 复制代码
# 同时输出到屏幕和文件
ls -la | tee output.log
​
# 追加(不覆盖)
ls -la | tee -a output.log
​
# 用 sudo 保存到需要权限的文件
echo "127.0.0.1 example.com" | sudo tee -a /etc/hosts

sudo + tee 的经典用法:

bash 复制代码
# 把内容写到 root 拥有的文件
echo "新的配置" | sudo tee /etc/myapp.conf >/dev/null

> /dev/null 抑制 tee 自身的输出,只保留写文件的效果。

3.3 crontab:定时任务

crontab 是 Linux 的定时任务工具。语法是 crontab -e 编辑、crontab -l 查看、crontab -r 删除。

cron 的时间格式:分 时 日 月 周 命令

bash 复制代码
# 每天凌晨 3 点跑
0 3 * * * /opt/backup.sh
​
# 每 5 分钟跑
*/5 * * * * /opt/monitor.sh
​
# 每周一上午 9 点
0 9 * * 1 /opt/weekly.sh
​
# 每月 1 号凌晨
0 0 1 * * /opt/monthly.sh

几个特殊写法:

  • *:每(每分、每时、每天......)
  • */N:每 N(每 5 分钟、每 2 小时)
  • 1,3,5:1 点、3 点、5 点
  • 1-5:1 到 5(连续)

crontab 的几个坑

  1. 环境变量不同:crontab 默认的 PATH 很有限,脚本里要用绝对路径
  2. 输出不会显示:crontab 的输出默认会发邮件,现代服务器没有本地邮件------用 >> /var/log/cron.log 2>&1 重定向
  3. 工作目录不同:crontab 的工作目录是 $HOME,脚本里要 cd 到正确目录

实操建议:写一个 crontab 行时,明确所有路径:

javascript 复制代码
0 3 * * * /bin/bash /opt/backup.sh >> /var/log/backup.log 2>&1

3.4 screen / tmux:终端复用

screen 和 tmux 是"终端复用器"------让你在一个终端里开多个窗口,断开后能恢复。

tmux 是新一代标准,比 screen 配置更灵活,如果有 tmux 就用 tmux。

bash 复制代码
# 启动新会话
tmux
​
# 启动命名会话
tmux new -s mywork
​
# 列出所有会话
tmux ls
​
# 重新连接
tmux attach -t mywork
​
# 在会话里:
# Ctrl+B 然后 c:创建新窗口
# Ctrl+B 然后 n:下一个窗口
# Ctrl+B 然后 p:上一个窗口
# Ctrl+B 然后 d:分离会话(detach)

screen 跟 tmux 类似的快捷键(Ctrl+A 替代 Ctrl+B)。

核心场景 :远程操作时启动一个长期任务,用 screen/tmux 保护它不被断开中断。比如升级服务时 screen -S upgrade,跑完后再 screen -r upgrade 看结果。

3.5 watch:周期执行

watch 每隔一段时间执行一次命令,用来观察变化。

bash 复制代码
# 每 2 秒看一次磁盘
watch -n 2 df -h
​
# 每秒看一次进程
watch -n 1 "ps aux | grep nginx"
​
# 高亮变化的部分
watch -d "ls -la /tmp/"
​
# 退出码非 0 时停止
watch -e "curl -sf https://api.example.com/health"

watch 是动态监控的好工具,比手动重复命令省事。

3.6 其他值得知道的工具

at :一次性定时任务。at 23:00 进入交互模式,输入命令,Ctrl+D 结束。比 crontab 简单,但用得不多。

script :记录终端会话。script -t timing.log session.log,退出后用 scriptreplay 回放。

timeout :限时执行。timeout 30 long_command,30 秒后发 TERM,超时保护。

bash 复制代码
# 给命令加超时
timeout 10 curl -s https://slow-api.example.com
​
# 5 秒后还没下载完就 kill
timeout 5 wget https://example.com/big-file.iso

envsubst :环境变量替换。echo "Hello $NAME" | envsubst 会把 $NAME 替换成环境变量值。

arduino 复制代码
# 渲染配置模板
envsubst < config.template > config.conf

四、总结

这一篇我们讲完了 shell 常用命令系列的最后一部分------归档、权限、进阶工具。三篇系列合起来,覆盖了日常 95% 的工具场景。

三篇内容回顾:

第一篇讲的是文件操作和文本处理------ls、cp、find、cat、less、head、tail、sort、uniq、cut、paste、tr、join 。

第二篇讲的是进程、网络、系统信息------ps、top、kill、nohup、ping、curl、ssh、scp、rsync、ss、dig、nc、date、free、df 。

第三篇(这一篇)讲的是归档、权限、进阶工具------tar、gzip、chmod、chown、sudo、xargs、tee、crontab、tmux 。

三篇读下来,应该对 shell 日常命令有了完整印象,知道什么时候用哪个、怎么组合。

相关推荐
柒号华仔1 天前
「速通Shell」常用命令(中)——进程、网络与系统信息
shell
YuSun_WK1 天前
shell脚本
shell·脚本
柒号华仔4 天前
「速通Shell」Shell 脚本测试详解
shell
柒号华仔5 天前
「速通Shell」Shell 脚本模块化
shell
柒号华仔6 天前
「速通Shell」Shell编程的错误处理与日志
shell
柒号华仔7 天前
「速通Shell」Shell 数组、关联数组与 mapfile
shell
苏灿烤鱼9 天前
一套进程代替八件套,桌面更稳还是单点更大
linux·github·shell
茶本无香9 天前
通用报表自动化框架:Java调用Shell传参执行PostgreSQL SQL模板
java·sql·postgresql·shell
柒号华仔10 天前
「速通Shell」Shell 循环与遍历
shell·编程语言