Skip to content

Linux 速查表

开源的类 Unix 操作系统内核及发行版。

01

入门基础

基本文件命令

ls -la 显示所有文件包括隐藏文件。cd ~ 回到主目录,cd - 在两个目录间切换。mkdir -p 按需创建父目录。rm -r 用于删除非空目录。

linux
# list files
ls -la          # long format, all files
ls -lh          # human-readable sizes
ls -lt          # sort by modification time

# current directory
pwd

# change directory
cd /home/user
cd ..           # go up one level
cd ~            # go home
cd -            # go to previous directory

# create/remove directories
mkdir newdir
mkdir -p path/to/dir   # create parents
rmdir emptydir
rm -r nonempty          # remove recursively

获取帮助

man 是主要的文档系统。章节:1=命令,2=系统调用,3=库函数,4=设备,5=文件格式,8=管理。man -k(或 apropos)搜索描述。--help 给出简洁摘要。tldr 提供实用示例,需单独安装(npm install -g tldr)。

linux
# manual pages
man ls                  # full documentation
man 5 crontab           # section 5 (file formats)
man -k password         # search by keyword (apropos)

# info pages (GNU tools, more detailed)
info coreutils
info ls

# quick help flags
command --help
ls --help
git --help

# tldr: community cheat sheets (install separately)
tldr tar
tldr find

# whatis: one-line description
whatis ls

# where is the binary / source / man page
whereis python3

命令历史与快捷方式

!! 重复上一条命令(sudo !! 是经典的'忘记 sudo'修复法)。!N 运行历史中第 N 条命令。!$ 是最后一个参数。Ctrl+R 是交互式反向搜索——再按一次查找更早的匹配。历史记录存储在 ~/.bash_history;HISTSIZE 控制内存中的大小,HISTFILESIZE 控制文件大小。

linux
# history expansion
history                 # show command history
!!                      # repeat last command
sudo !!                 # repeat last command as root
!42                     # run command #42 from history
!ls                     # run last command starting with ls
!$                      # last argument of last command
!!:gs/old/new/          # substitute in last command

# search history (interactive)
# Ctrl+R then type to search backward

# clear history
history -c              # clear current session
# edit ~/.bashrc HISTSIZE and HISTFILESIZE

# save and reload history
history -a              # append to history file
history -r              # reload from file

文件类型与识别

file 检查文件的魔数字节来确定其真实类型——比扩展名可靠得多。ls -F 附加类型标识(* 可执行,/ 目录,@ 符号链接,= 套接字)。stat 显示完整的 inode 元数据,包括三个时间戳:Access(atime)、Modify(mtime,内容)、Change(ctime,元数据)。

linux
# identify file type by content (not extension)
file document.pdf       # PDF document
file image.png          # PNG image data
file script.sh          # ASCII text executable
file /bin/ls            # ELF 64-bit LSB executable

# file with multiple files
file *.txt

# show MIME type
file --mime-type video.mp4   # video/mp4

# ls -F shows type indicator
ls -F
# file*       (executable)
# dir/        (directory)
# link@       (symlink)
# socket=     (socket)

# stat: detailed file info
stat file.txt
# Size, Blocks, IO Block, Device, Inode, Links,
# Access/Modify/Change/Birth times

终端导航快捷键

这些 Readline 快捷键在 bash 和大多数 shell 中通用。Ctrl+A/E 跳到行首/行尾。Ctrl+W/U/K 删除文本——Ctrl+Y 粘贴回来(kill ring)。Ctrl+R 搜索历史。Ctrl+L 清屏。Ctrl+S 冻结输出(常见的'终端假死'原因——Ctrl+Q 恢复)。掌握这些可以大幅提升命令行编辑速度。

linux
# cursor movement
Ctrl+A     # move to beginning of line
Ctrl+E     # move to end of line
Ctrl+B     # move back one char
Ctrl+F     # move forward one char

# editing
Ctrl+D     # delete char under cursor (or EOF/exit)
Ctrl+H     # delete char before cursor (backspace)
Ctrl+W     # delete word before cursor
Ctrl+U     # delete from cursor to beginning
Ctrl+K     # delete from cursor to end
Ctrl+Y     # paste (yank) deleted text back

# job control
Ctrl+C     # send SIGINT (interrupt)
Ctrl+Z     # suspend (send SIGTSTP)
Ctrl+D     # end of input / exit shell

# screen
Ctrl+L     # clear screen (same as clear)
Ctrl+S     # stop output (freeze)
Ctrl+Q     # resume output

# Alt shortcuts
Alt+B / Alt+F    # move back/forward by word
Alt+Backspace    # delete word backward

环境变量

环境变量在导出后被子进程继承。$PATH 决定 shell 查找命令的位置——目录按冒号分隔的顺序搜索。~/.bashrc 用于交互式非登录 shell;~/.profile 或 ~/.bash_profile 用于登录 shell。编辑后始终 source 文件以应用更改。使用 printenv VAR 检查单个变量而不进行扩展。

linux
# view all environment variables
env
printenv

# view specific variable
echo $HOME
echo $PATH
echo $USER

# set a variable (current shell only)
MYVAR="hello"
echo $MYVAR

# export to child processes
export PATH="$PATH:/opt/bin"
export EDITOR=nano

# set and export in one step
export MYVAR="hello"

# unset a variable
unset MYVAR

# common variables
# $HOME    user home directory
# $PATH    command search path
# $USER    current username
# $SHELL   current shell path
# $PWD     current working directory
# $OLDPWD  previous directory
# $PS1     prompt string

# persistent: add to ~/.bashrc or ~/.profile
echo 'export EDITOR=vim' >> ~/.bashrc
source ~/.bashrc
02

文件操作

复制文件 (cp)

cp 复制文件。目录需要 -r(或 -R)。-i 在覆盖前提示(建议以避免数据丢失)。-p 保留元数据;-a 是归档模式(保留所有内容,包括符号链接——非常适合备份)。-u 仅在源文件更新时才复制。在覆盖有风险的脚本中始终使用 -i。

linux
# copy a file
cp source.txt dest.txt

# copy to a directory
cp file.txt /backup/

# copy multiple files to a directory
cp file1.txt file2.txt /backup/

# copy directories recursively
cp -r src_dir/ dest_dir/

# interactive (prompt before overwrite)
cp -i file.txt /backup/

# preserve attributes (timestamps, permissions, ownership)
cp -p file.txt /backup/
cp -a src_dir/ dest_dir/    # archive mode (-rdp)

# only copy if source is newer
cp -u file.txt /backup/

# verbose (show what is being copied)
cp -v file.txt /backup/

# force overwrite
cp -f file.txt /backup/

移动与重命名 (mv)

mv 既是移动也是重命名——它更新目录条目而不复制数据(在同一文件系统上瞬时完成)。-i 在覆盖前提示。mv -n 防止覆盖已有文件。rename 命令(Debian/Ubuntu 上的 Perl 版本)使用正则表达式批量重命名——比 mv 循环强大得多。注意:rename 语法因发行版而异(util-linux vs perl 版本)。

linux
# rename a file
mv oldname.txt newname.txt

# move file to another directory
mv file.txt /target/dir/

# move multiple files
mv file1.txt file2.txt /target/dir/

# interactive (prompt before overwrite)
mv -i file.txt /target/

# force overwrite
mv -f file.txt /target/

# no overwrite (don't replace existing)
mv -n file.txt /target/

# move only if newer
mv -u file.txt /target/

# verbose
mv -v olddir/ newdir/

# rename batch with rename command
rename 's/\.txt$/.md/' *.txt
rename .JPG .jpg *.JPG

删除文件 (rm)

rm 永久删除文件(没有回收站)。目录需要 -r。-rf 很危险——它递归删除且不提示;始终仔细检查路径。永远不要运行 rm -rf / 或在 $VAR 可能为空时运行 rm -rf $VAR/。考虑使用 trash-cli 进行可恢复的删除。find -delete 用于基于模式的删除更安全,因为可以先不带 -delete 测试。

linux
# remove a file
rm file.txt

# remove multiple files
rm file1.txt file2.txt

# interactive (prompt for each file)
rm -i file.txt

# force (ignore nonexistent, no prompt)
rm -f file.txt

# remove directory recursively
rm -r directory/
rm -rf directory/        # force + recursive (DANGEROUS)

# verbose
rm -v *.tmp

# remove files matching pattern
find . -name "*.bak" -delete
find . -name "*.log" -mtime +30 -delete

# safer alternative: trash-cli
trash-put file.txt
trash-list
trash-restore

创建文件 (touch)

touch 创建空文件或更新现有文件的时间戳。不带选项时,它将 atime 和 mtime 都设为当前时间。-t 设置特定时间戳。-r 从参考文件复制时间戳。要创建带内容的文件,使用重定向(>)或 here-document。touch 常用于创建占位文件或强制 make 重新构建目标。

linux
# create an empty file
touch newfile.txt

# create multiple empty files
touch file1.txt file2.txt file3.txt

# update access and modification time to now
touch existing.txt

# set specific time (YYYYMMDDHHMM format)
touch -t 202401011200 file.txt       # Jan 1, 2024 12:00

# set only access time
touch -a file.txt

# set only modification time
touch -m file.txt

# use time from another file
touch -r reference.txt target.txt

# create file with content
echo "content" > file.txt
cat > file.txt << 'EOF'
line 1
line 2
EOF

硬链接与符号链接 (ln)

硬链接共享相同的 inode(数据)——删除一个不会删除数据,直到所有链接都被移除。它们不能跨文件系统或链接到目录。符号链接是路径引用——如果目标移动或删除则会断开,但可以跨文件系统和链接到目录。使用 ln -s 创建符号链接(最常用)。readlink -f 解析完整链到真实文件。

linux
# hard link (same inode, same filesystem only)
ln original.txt hardlink.txt

# symbolic link (symlink, path reference)
ln -s /path/to/target symlink_name
ln -s original.txt softlink.txt

# force recreate a symlink
ln -sf /new/target symlink_name

# symbolic link to a directory
ln -s /var/log /home/user/logs

# view link target
readlink symlink
readlink -f symlink        # canonical absolute path
ls -l symlink              # show what it points to

# find broken symlinks
find . -type l ! -exec test -e {} \; -print

# count hard links to a file
ls -li file.txt            # 2nd column is link count

# remove a symlink
rm symlink_name
unlink symlink_name

文件元数据 (stat, basename, dirname)

stat 显示完整的 inode 元数据。basename 和 dirname 分解路径——在处理文件列表的脚本中必不可少。realpath 将相对路径和符号链接解析为绝对规范路径。stat -c 允许自定义输出格式(%n=名称,%s=大小,%y=mtime,%a=八进制权限)——在脚本中很有用。这些工具替代了脆弱的参数扩展来处理路径。

linux
# stat: full file information
stat file.txt
# Size: 1024  Blocks: 8  IO Block: 4096
# Device: 801h/2049d  Inode: 1234567
# Links: 1
# Access: (0644/-rw-r--r--)  Uid: 1000  Gid: 1000
# Access/Modify/Change: 2024-01-01 12:00:00

# custom format
stat -c '%n %s bytes' file.txt
stat -c '%y' file.txt            # modification time

# basename: extract filename from path
basename /var/log/syslog         # syslog
basename /var/log/syslog.log .log  # syslog

# dirname: extract directory from path
dirname /var/log/syslog          # /var/log

# realpath: resolve to absolute path
realpath ../file.txt
realpath -s symlink              # physical path (no symlink resolution)

# file size only
stat -c %s file.txt              # bytes
du -h file.txt | cut -f1         # human-readable
03

目录操作

创建目录 (mkdir)

mkdir -p 按需创建父目录,且目录已存在时不报错——对幂等脚本至关重要。-m 直接设置权限(覆盖 umask)。大括号扩展({a,b,c})与 mkdir -p 结合可一条命令创建复杂的目录树。这是搭建项目结构的常见模式。

linux
# create a single directory
mkdir newdir

# create nested directories
mkdir -p path/to/deep/dir

# create multiple directories
mkdir dir1 dir2 dir3

# create with specific permissions
mkdir -m 755 publicdir
mkdir -m 700 privatedir

# verbose output
mkdir -v newdir

# create parent dirs with permissions
mkdir -p -m 755 /opt/myapp/{bin,lib,etc}

# create a directory tree at once
mkdir -p project/{src,tests,docs}
mkdir -p project/src/{main,utils}
mkdir -p project/{src/{main,utils},tests,docs}

删除目录 (rmdir, rm)

rmdir 只删除空目录——安全但有限。rm -r 递归删除非空目录。rm -rf 是核武器选项:始终先验证路径。find -empty -delete 模式只删除空目录而不触及有内容的目录。在脚本中,始终检查变量非空后再用 rm -rf,以避免意外删除 /。

linux
# remove an empty directory
rmdir emptydir

# remove directory with contents
rm -r directory/

# force remove (no prompt)
rm -rf directory/

# remove empty directories recursively (find)
find . -type d -empty -delete
find . -type d -empty -exec rmdir {} \;

# remove directory with confirmation
rm -ri directory/

# safe removal pattern in scripts
DIR="/tmp/mydir"
if [ -n "$DIR" ] && [ -d "$DIR" ]; then
    rm -rf "$DIR"
fi

# move to trash instead
trash-put directory/

目录列表与树形结构

ls -d */ 只列出目录。tree 提供可视化的层级结构——-L 限制深度,-I 排除模式(排除 node_modules/.git 非常有用)。对于大型目录树,结合 tree -d -L 2 快速概览。ls -1(数字 1)每行一个文件——用于管道到 wc -l 计数很方便。

linux
# list directory contents
ls -la                    # all files, long format
ls -lh                    # human-readable sizes
ls -lt                    # sort by time (newest first)
ls -lS                    # sort by size (largest first)
ls -lr                    # reverse order
ls -R                     # recursive listing
ls -d */                  # list only directories

# tree view (install separately: apt install tree)
tree                      # show directory tree
tree -L 2                 # limit depth to 2
tree -d                   # directories only
tree -a                   # include hidden files
tree -h                   # show file sizes
tree --dirsfirst          # dirs before files
tree -I 'node_modules|.git'  # ignore patterns
tree -H . -o tree.html    # output as HTML

# count files in directory
ls -1 | wc -l
find . -maxdepth 1 -type f | wc -l

目录大小 (du)

du 测量磁盘使用量。-s(摘要)只显示总计,-h 使其人类可读。du -sh */ 显示直接子目录的大小。sort -rh 按人类可读大小倒序排列(最大的在前)。--exclude 跳过模式。apparent-size 与默认值的区别:apparent 显示逻辑文件大小,默认显示实际分配的磁盘块(由于块大小可能更大)。

linux
# size of current directory (total)
du -sh .

# size of specific directories
du -sh /var/log /tmp /home

# size of all subdirectories
du -sh */

# sort directories by size (largest first)
du -sh * | sort -rh

# find the 10 largest directories
du -sh * | sort -rh | head -10

# include hidden files/dirs
du -sh .[!.]*

# maximum depth
du -h --max-depth=1
du -h -d 1                  # short form

# apparent size vs disk usage
du -sh --apparent-size file  # logical size
du -sh file                   # actual disk blocks

# exclude directories
du -sh --exclude='*.log' .
du -sh --exclude=node_modules .

目录栈 (pushd, popd)

pushd/popd 管理目录栈——pushd 保存当前目录并导航到新目录;popd 返回到保存的目录。dirs 显示栈。这比 cd -(只在两个目录间切换)更强大。在需要在多个目录间导航并返回的脚本中很有用。+N 语法按位置轮转或移除。

linux
# push directory onto stack and cd into it
pushd /var/log
# pushes current dir, then cd to /var/log

# push another
pushd /tmp
# stack: /tmp /var/log /home/user

# pop back to previous directory
popd
# returns to /var/log

# list the directory stack
dirs
dirs -v           # verbose (numbered)
dirs -c           # clear the stack

# navigate by index
pushd +2          # rotate to 3rd entry
popd +1           # remove 2nd entry

# practical: save current dir, work, return
pushd /etc
cp config.conf ~/backup/
popd              # back to where we were

# alternative: use cd - for simple toggle
cd /var/log
cd -              # back to previous directory
04

文件查看

cat 与 tac

cat 将整个文件输出到 stdout——小文件没问题,大文件请用 less/head。cat -n 编号行。cat -A 显示隐藏字符(制表符、行尾)——调试格式问题很有用。tac 反转行序(cat 的倒序)。cat 也用于连接文件和重定向输入。交互式查看大文件请使用 less。

linux
# display entire file
cat file.txt

# concatenate multiple files
cat file1.txt file2.txt > combined.txt

# display with line numbers
cat -n file.txt

# display with non-printing characters
cat -A file.txt           # show tabs as ^I, line ends as $
cat -v file.txt           # show non-printing chars
cat -e file.txt           # show line ends as $
cat -t file.txt           # show tabs as ^I

# append to a file
cat >> file.txt << 'EOF'
appended line
EOF

# tac: reverse line order
tac file.txt              # last line first

# create file from stdin
cat > newfile.txt
# type content, Ctrl+D to end

less 分页器

less 是标准分页器——比 more 好得多,因为它允许向后导航。按键类似 vim(j/k/g/G)。/ 向前搜索,? 向后搜索。F 进入'跟随模式'(类似 tail -f)用于查看日志。如果配置了 lesspipe,less 会自动处理压缩文件。按 v 在 $EDITOR 中打开当前文件进行快速编辑。

linux
# view a file
less file.txt

# view command output
dmesg | less
ls -la /etc | less

# navigation inside less:
#   space / f     forward one page
#   b             backward one page
#   j / k         down / up one line
#   g             go to beginning
#   G             go to end
#   /pattern      search forward
#   ?pattern      search backward
#   n             next match
#   N             previous match
#   v             open in editor ($EDITOR)
#   F             follow mode (like tail -f)
#   q             quit

# useful flags
less -N file.txt          # show line numbers
less -S file.txt          # chop long lines
less -i file.txt          # case-insensitive search
less +/pattern file.txt   # open at first match

# view compressed files
less file.gz              # auto-decompresses (if lesspipe installed)

head 与 tail

head 显示文件开头,tail 显示文件末尾。tail -f 对于实时监控日志文件至关重要。tail -F(大写)通过重新打开文件处理文件轮转(当日志被重命名/截断时)。head -n -N 显示除最后 N 行外的所有内容。对于大文件,head/tail 是即时的(它们不会读取整个文件)。

linux
# first 10 lines (default)
head file.txt
# last 10 lines (default)
tail file.txt

# first N lines
head -n 20 file.txt
head -20 file.txt

# last N lines
tail -n 20 file.txt
tail -20 file.txt

# all but last N lines
head -n -5 file.txt       # all except last 5 lines

# first N bytes
head -c 100 file.txt
tail -c 100 file.txt

# follow a log file (live updates)
tail -f /var/log/syslog

# follow with retry (handles log rotation)
tail -F /var/log/app.log

# show last 5 lines, then follow
tail -n 5 -f app.log

# multiple files
tail -n 5 file1.txt file2.txt

查看特定行

sed -n 'Np' 打印特定行号。awk 配合 NR(记录号)对范围和条件更灵活。(head; tail) 技巧显示大文件的两端。nl 和 cat -n 编号行。hexdump/xxd 以十六进制显示二进制文件——检查非文本文件、调试文件格式或恢复数据的必备工具。

linux
# show line N (e.g., line 10)
sed -n '10p' file.txt

# show lines M to N
sed -n '10,20p' file.txt
awk 'NR>=10 && NR<=20' file.txt

# show first and last N lines
(head -5; echo "..."; tail -5) < file.txt

# show lines matching pattern
sed -n '/pattern/p' file.txt
awk '/pattern/' file.txt

# show every Nth line
awk 'NR % 3 == 0' file.txt     # every 3rd line
sed -n '0~3p' file.txt          # every 3rd line (GNU)

# number lines
nl file.txt
cat -n file.txt
grep -n "" file.txt

# show file in hex
hexdump -C file.bin
xxd file.bin
od -A x -t x1z file.bin

字数与行数统计 (wc)

wc(word count)报告行数(-l)、单词数(-w)、字节数(-c)、字符数(-m,尊重编码)和最长行长度(-L)。给定多个文件时,显示每个文件的计数和总计。grep | wc -l 模式计算匹配行——但 grep -c 更高效(无管道)。计算文件数时,ls -1 | wc -l 很快,但 find 递归计数更准确。

linux
# count lines, words, and bytes
wc file.txt
#   10   50  300 file.txt
#  lines words bytes

# count lines only
wc -l file.txt

# count words only
wc -w file.txt

# count characters only
wc -m file.txt

# count bytes only
wc -c file.txt

# count the longest line length
wc -L file.txt

# count files in a directory
ls -1 | wc -l
find . -type f | wc -l

# count total lines in multiple files
wc -l *.py

# count matching lines (grep + wc)
grep "error" log.txt | wc -l

# count unique lines
sort file.txt | uniq | wc -l
07

文本处理

sed — 流编辑器

sed 非交互式编辑文本流。s 替换(g 为全局);d 删除;p 打印。-i 就地编辑(始终先不带 -i 测试,或用 -i.bak 备份)。分隔符可以是任何字符——对路径使用 | 或 # 以避免转义斜杠。-E 启用扩展正则,捕获组语法更清晰。sed 逐行处理。

linux
# substitute (replace first occurrence per line)
sed 's/old/new/' file.txt

# substitute all occurrences (global)
sed 's/old/new/g' file.txt

# case-insensitive (GNU sed)
sed 's/old/new/gi' file.txt

# in-place editing
sed -i 's/old/new/g' file.txt
sed -i.bak 's/old/new/g' file.txt   # keep backup

# delete lines
sed '/^#/d' file.txt           # delete comment lines
sed '/^$/d' file.txt           # delete blank lines
sed '5d' file.txt              # delete line 5
sed '5,10d' file.txt           # delete lines 5-10

# print specific lines
sed -n '10,20p' file.txt       # lines 10-20
sed -n '/pattern/p' file.txt   # matching lines

# different delimiter for paths
sed 's|/usr/local|/opt|g' paths.txt

# extended regex with capture groups
sed -E 's/([0-9]{4})-([0-9]{2})-([0-9]{2})/\3\/\2\/\1/' dates.txt

# multiple commands
sed -e 's/a/A/g' -e 's/b/B/g' file.txt

awk — 列处理

awk 是用于列数据的小型编程语言。$1、$2... 是字段;$0 是整行;$NF 是最后一个字段。-F 设置输入分隔符;OFS 设置输出。BEGIN 在处理前运行,END 在处理后运行。NR 是记录(行)号;NF 是字段计数。awk 非常适合 CSV/TSV 处理、日志分析和报告——比 cut 强大得多。

linux
# print columns (default separator: whitespace)
awk '{print $1}' file.txt           # first column
awk '{print $1, $3}' file.txt       # columns 1 and 3
awk '{print $NF}' file.txt          # last column
awk -F: '{print $1}' /etc/passwd    # split on :

# filter and print
awk '$3 > 100' file.txt             # col 3 > 100
awk '$1 == "ERROR" {print $2}' log  # col 2 of ERROR lines
awk 'NR == 5' file.txt              # 5th line only
awk 'NR >= 10 && NR <= 20' file.txt # lines 10-20

# BEGIN and END blocks (sum, average)
awk '{sum += $1} END {print sum}' nums.txt
awk '{sum += $2; count++} END {print sum/count}' data.txt

# field separator and output
awk -F, 'BEGIN {OFS="|"} {print $1, $2}' csv.txt

# count lines matching pattern
awk '/error/ {count++} END {print count}' log

# built-in variables: NR (row), NF (fields), FS, OFS
awk '{print NR, NF, $0}' file.txt

cut 与 paste

cut 提取字段(-f 配合 -d 分隔符)或字符位置(-c)。它快速但有限——不支持引号,所以带引号逗号的 CSV 会出错。paste 并排合并文件。join 在公共排序字段上合并文件(类似 SQL JOIN)。expand/unexpand 在制表符和空格间转换。复杂 CSV 处理请用 awk 或专用工具如 csvkit。

linux
# cut: extract fields by delimiter
cut -d: -f1 /etc/passwd            # field 1, delimiter :
cut -d, -f2,3 data.csv             # fields 2 and 3

# cut: extract character positions
cut -c1-5 file.txt                 # characters 1-5
cut -c1- file.txt                  # from char 1 to end

# cut: extract bytes (for multibyte)
cut -b1-10 file.txt

# paste: merge files line by line
paste file1.txt file2.txt          # tab-separated
paste -d',' file1.txt file2.txt    # comma-separated

# paste: serial (all lines of file1, then file2)
paste -s file1.txt                 # lines into one line
paste -s -d',' file1.txt file2.txt

# join: combine on a common field
join -t, -1 1 -2 1 file1.csv file2.csv

# expand/unexpand tabs
expand file.txt                    # tabs to spaces
unexpand -a file.txt               # spaces to tabs

sort 与 uniq

sort 排序行(-n 数字,-r 反向,-h 人类可读,-k 字段,-t 分隔符)。uniq 只移除相邻的重复项——始终先通过 sort 管道。uniq -c 计数;sort -rn 给出频率排名。comm 比较两个已排序文件:-12 显示共有,-23 显示只在第一个文件中,-13 显示只在第二个文件中。sort | uniq -c | sort -rn 模式是经典的频率分析管道。

linux
# sort lines
sort file.txt                      # alphabetical
sort -n nums.txt                   # numeric
sort -rn nums.txt                  # reverse numeric
sort -h sizes.txt                  # human-readable (1K, 2M, 3G)
sort -R file.txt                   # random order
sort -u file.txt                   # sort + unique

# sort by field
sort -t: -k3 -n /etc/passwd        # by 3rd field, numeric
sort -t, -k2 data.csv              # by 2nd field

# sort by multiple keys
sort -k1,1 -k2n file.txt           # key1 alpha, key2 numeric

# uniq: filter adjacent duplicates
sort file.txt | uniq               # unique lines
sort file.txt | uniq -c            # count occurrences
sort file.txt | uniq -d            # only duplicates
sort file.txt | uniq -u            # only unique lines

# top 10 most frequent lines
sort file.txt | uniq -c | sort -rn | head -10

# compare two sorted files
comm -12 <(sort a.txt) <(sort b.txt)   # common lines
comm -23 <(sort a.txt) <(sort b.txt)   # only in a
comm -13 <(sort a.txt) <(sort b.txt)   # only in b

tr — 字符转换

tr 转换或删除字符(不是正则——只是字符集)。-d 删除,-s 压缩重复,-c 补集(反转集合)。它非常适合大小写转换、分隔符交换和数据清理。tr ',' '\n' 将 CSV 转换为每行一个值。tr -cd '0-9' 只提取数字。注意:tr 处理字符而非字符串,所以不能替换多字符模式——用 sed。

linux
# translate characters
echo "Hello" | tr 'a-z' 'A-Z'       # HELLO (uppercase)
echo "Hello" | tr 'A-Z' 'a-z'       # hello (lowercase)

# swap characters
echo "abc" | tr 'abc' 'bca'         # bca

# delete characters
echo "hello" | tr -d 'l'            # heo
echo "Hello World" | tr -d ' '      # HelloWorld

# squeeze repeated characters
echo "aaabbbccc" | tr -s 'abc'      # abc
tr -s ' ' < file.txt                # squeeze repeated spaces

# complement (delete everything except)
echo "Hello123" | tr -cd '0-9'      # 123 (keep digits only)
echo "Hello123" | tr -cd 'A-Za-z'   # Hello

# convert delimiter
echo "a,b,c" | tr ',' '\n'          # a\nb\nc (one per line)
echo "a,b,c" | tr ',' '\t'          # tab-separated

# ROT13 cipher
echo "Hello" | tr 'A-Za-z' 'N-ZA-Mn-za-m'

# remove non-printable characters
tr -cd '\11\12\15\40-\176' < file.txt

tee 与 column

tee 将输出同时分流到文件和 stdout——在管道中记录日志必不可少。sudo tee 写入需要 root 权限的文件而无需以 root 运行整个管道。column -t 将文本对齐成整齐的列(非常适合显示 CSV)。-s 指定输入分隔符,-o 指定输出分隔符。fmt 和 fold 重新排版文本——fmt 合并段落,fold 按宽度硬换行。

linux
# tee: write to file AND stdout
echo "hello" | tee file.txt
echo "hello" | tee -a file.txt       # append

# tee to multiple files
echo "data" | tee f1.txt f2.txt f3.txt

# tee in a pipeline (log while transforming)
ls -la | tee output.txt | grep ".py"

# tee with sudo (write to privileged file)
echo "config" | sudo tee /etc/myapp.conf

# column: format as aligned columns
column -t file.txt
echo -e "a b c\n1 2 3" | column -t

# column with custom delimiter
column -t -s, data.csv
column -t -s: /etc/passwd

# column with specific separator for output
column -t -o " | " file.txt

# fmt: reformat paragraph width
fmt -w 60 file.txt

# fold: wrap lines at width
fold -w 80 file.txt
fold -w 80 -s file.txt   # break at spaces only
08

权限与所有权

查看权限

权限是三个三元组:所有者、组、其他。每个位置是 r(4)、w(2)、x(1)。所以 755 = rwxr-xr-x,644 = rw-r--r--。对于目录,x 表示'可以访问'(cd 进入),r 表示'可以列出',w 表示'可以创建/删除文件'。stat -c '%a' 显示八进制权限。ls -l 的第一个字符是文件类型(- 文件,d 目录,l 符号链接,b 块设备,c 字符设备)。

linux
# view file permissions
ls -l file.txt
# -rw-r--r-- 1 user group 1024 Jan 1 10:00 file.txt
#  ^^^ ^^^ ^^^
#  owner group others
#  rwx  r-x  r-x  = 755

# permission breakdown:
# - = regular file, d = directory, l = symlink
# r = read (4), w = write (2), x = execute (1)

# view all files in directory
ls -la

# view permissions recursively
ls -lR /var/www

# view in octal format
stat -c '%a %n' file.txt        # 644 file.txt
stat -c '%a %n' *

# check current umask
umask                           # e.g., 0022

# directory permissions:
# r = list contents
# w = create/delete files
# x = access (cd into) directory

chmod — 数字模式

数字(八进制)表示法:每个数字代表所有者、组、其他。r=4,w=2,x=1——相加即可。755(rwxr-xr-x)用于目录和可执行文件;644(rw-r--r--)用于普通文件;600(rw-------)用于私有文件。Web 服务器的标准是目录=755,文件=644。基于 find 的递归模式对目录和文件应用不同权限——chmod -R 做不到这一点。

linux
# numeric (octal) notation
chmod 755 script.sh        # rwxr-xr-x
chmod 644 file.txt         # rw-r--r--
chmod 600 secrets.txt      # rw------- (private)
chmod 777 publicdir/       # rwxrwxrwx (DANGEROUS)
chmod 700 ~/.ssh           # rwx------ (for SSH)

# common patterns
chmod 755 directory/       # dirs: owner full, others read+execute
chmod 644 file.txt         # files: owner read+write, others read
chmod 600 config.env       # sensitive files: owner only
chmod 666 shared.txt       # everyone read+write (no execute)
chmod 444 readonly.txt     # everyone read only

# recursive
chmod -R 755 project/
chmod -R 644 *.txt          # won't work; use find

# recursive: dirs 755, files 644 (common web server setup)
find . -type d -exec chmod 755 {} \;
find . -type f -exec chmod 644 {} \;

# permission reference:
# 7=rwx 6=rw 5=rx 4=r 3=wx 2=w 1=x 0=none

chmod — 符号模式

符号表示法对增量更改更清晰:u/g/o/a(谁),+/-/=(操作),r/w/x/X(什么)。X(大写)仅对目录或已有执行权限的文件设置执行——非常适合递归 chmod。--reference 从另一个文件复制权限。粘滞位(+t)在目录上意味着只有文件所有者能删除自己的文件(用于 /tmp)。

linux
# symbolic notation
chmod u+x script.sh        # add execute for user
chmod g-w file.txt         # remove write for group
chmod o+r file.txt         # add read for others
chmod a+x script.sh        # add execute for all (a=all)

# combined changes
chmod u+x,g-w,o=r file.txt # user +x, group -w, others = read only
chmod ug+x file.txt        # add execute for user and group
chmod a=r file.txt         # set everyone to read only

# copy permissions from reference
chmod --reference=template.txt file.txt

# recursive
chmod -R u+rwX,go+rX .     # X = execute only for dirs/executables

# symbolic targets:
# u = user (owner)
# g = group
# o = others
# a = all (default)
# operators: + (add), - (remove), = (set exactly)
# permissions: r, w, x, X (execute if dir or already exec), s (SUID/SGID), t (sticky)

# set sticky bit on directory
chmod +t /tmp/shared
chmod 1777 /tmp/shared

chown 与 chgrp

chown 更改所有权(需要 root 或 sudo)。格式:owner:group——省略组只更改所有者,省略所有者(带冒号)只更改组。-R 递归进入目录。chgrp 是 chown :group 的快捷方式。--from 仅在当前所有者匹配时更改(条件式)。对于 Web 服务器,chown -R www-data:www-data 是标准。对符号链接始终使用 -h 以更改链接而非目标。

linux
# change owner
chown alice file.txt
chown alice file1.txt file2.txt

# change owner and group
chown alice:developers file.txt
chown alice:developers project/

# recursive
chown -R alice:developers project/

# change group only
chgrp developers file.txt
chown :developers file.txt        # alternative

# verbose
chown -v alice file.txt

# reference (copy ownership from another file)
chown --reference=reference.txt file.txt

# change ownership only if currently owned by specific user
chown --from=bob alice file.txt

# symbolic links (by default, changes the link target)
chown -h alice symlink            # change the link itself

# common patterns
chown -R www-data:www-data /var/www
chown root:root /etc/sudoers

# view ownership
ls -l file.txt                    # shows owner and group
stat -c '%U:%G' file.txt          # just owner:group

umask

umask 为新创建的文件和目录设置默认权限。它是一个掩码——从默认值中移除位(文件 666,目录 777)。常见值:022(标准,文件 644/目录 755),077(私有,文件 600/目录 700),002(组共享,文件 664/目录 775)。在 ~/.bashrc 或 /etc/profile 中设置以持久化。注意:umask 不能添加权限,只能移除。

linux
# view current umask
umask                  # e.g., 0022
umask -S               # symbolic: u=rwx,g=rx,o=rx

# set umask
umask 022              # new files: 644, dirs: 755
umask 077              # new files: 600, dirs: 700 (private)
umask 002              # new files: 664, dirs: 775 (group-writable)

# how umask works:
# default file perms: 666 (rw-rw-rw-)
# default dir perms:  777 (rwxrwxrwx)
# umask is SUBTRACTED (mask removed)
# umask 022: file = 666-022 = 644, dir = 777-022 = 755
# umask 077: file = 666-077 = 600, dir = 777-077 = 700

# set permanently: add to ~/.bashrc
echo 'umask 022' >> ~/.bashrc

# for security-sensitive environments
umask 077              # only owner can access new files

# for shared group work
umask 002              # group members can write new files

# umask does not affect execute bit on files
# (files are created without execute by default)

特殊权限 (SUID, SGID, 粘滞位)

SUID (4xxx):程序以文件所有者权限运行——passwd 需要它以 root 身份修改 /etc/shadow。SGID (2xxx):对可执行文件以组权限运行;对目录,新文件继承目录的组(对共享项目有用)。粘滞位 (1xxx):在目录上,只有文件所有者(或目录所有者/root)能删除文件——用于 /tmp。定期审计 SUID/SGID 文件,因为它们是提权向量。

linux
# SUID (Set User ID): runs as file owner
chmod u+s /usr/bin/passwd       # 4755 -> rwsr-xr-x
chmod 4755 myprogram

# SGID (Set Group ID): runs as group owner
chmod g+s /shared/dir           # dirs: new files inherit group
chmod 2755 /shared/project

# Sticky bit: only file owner can delete
chmod +t /tmp                   # 1777 -> rwxrwxrwt
chmod 1777 /shared/upload

# view special permissions
ls -l /usr/bin/sudo
# -rwsr-xr-x  (s in user position = SUID)
ls -ld /tmp
# drwxrwxrwt  (t in others position = sticky)

# find SUID files (security audit)
find / -perm -4000 -type f 2>/dev/null

# find SGID files
find / -perm -2000 -type f 2>/dev/null

# find sticky directories
find / -perm -1000 -type d 2>/dev/null

# numeric special bits:
# 1 = sticky, 2 = SGID, 4 = SUID
# chmod 4755 = SUID + 755
# chmod 2755 = SGID + 755
# chmod 1777 = sticky + 777

# uppercase S/T means execute bit is NOT set (usually an error)
# rws = SUID + execute, rwS = SUID without execute
09

用户与组

用户管理

useradd 创建用户(底层命令;Debian 上 adduser 是更友好的封装)。-m 创建主目录;-s 设置 shell;-c 设置全名;-G 添加到附加组。usermod -aG 追加到组而不移除现有组(始终用 -a 配合 -G)。userdel -r 移除主目录。passwd 设置密码。/etc/passwd 存储用户信息;/etc/shadow 存储密码哈希。

linux
# add a new user
sudo useradd -m -s /bin/bash alice
# -m: create home directory
# -s: specify login shell

# add user with full options
sudo useradd -m -s /bin/bash -c "Alice Smith" -G sudo,docker alice

# set password
sudo passwd alice

# delete a user
sudo userdel alice
sudo userdel -r alice         # remove home directory too

# modify user
sudo usermod -aG docker alice   # append to group (-a = append)
sudo usermod -s /bin/zsh alice  # change shell
sudo usermod -L alice           # lock account
sudo usermod -U alice           # unlock account
sudo usermod -l newname oldname # rename user

# view user info
id alice                      # uid, gid, groups
finger alice                  # detailed info (if installed)

# change login shell
chsh -s /bin/zsh

# list all users
cat /etc/passwd | cut -d: -f1
getent passwd | cut -d: -f1

组管理

组将用户组织以共享访问。groupadd/groupdel/groupmod 管理组。usermod -aG(追加到组)是添加用户的标准方式——不带 -a 会替换所有附加组。gpasswd 是替代工具。/etc/group 存储组定义。newgrp 启动一个具有不同主组的新 shell(在创建应该组拥有的文件时有用)。

linux
# create a group
sudo groupadd developers

# create group with specific GID
sudo groupadd -g 2000 developers

# delete a group
sudo groupdel developers

# modify group
sudo groupmod -n devs developers    # rename
sudo groupmod -g 2001 developers    # change GID

# add user to group
sudo usermod -aG docker alice       # append to group
sudo gpasswd -a alice developers    # alternative

# remove user from group
sudo gpasswd -d alice developers
sudo deluser alice developers       # Debian/Ubuntu

# list groups
cat /etc/group | cut -d: -f1
getent group

# view groups for a user
groups alice
id alice

# set group administrator
sudo gpasswd -A alice developers

# temporarily switch primary group
newgrp developers                  # new shell with group as primary

# view group members
getent group developers            # lists members
grep developers /etc/group

密码管理

passwd 更改密码。-l 锁定账户(在哈希中加 !);-u 解锁。-e 强制下次登录时更改密码。chage 管理密码老化策略:-M(最大天数),-m(最小天数),-W(警告天数),-E(过期日期)。密码哈希存储在 /etc/shadow(仅 root 可读),而非 /etc/passwd。良好的密码策略要求定期更改和复杂性要求。

linux
# change your own password
passwd

# change another user's password (requires root)
sudo passwd alice

# set password interactively
sudo passwd alice
# Enter new password: ******
# Retype new password: ******

# lock/unlock a password
sudo passwd -l alice          # lock (prepends !)
sudo passwd -u alice          # unlock

# force password change on next login
sudo passwd -e alice
sudo chage -d 0 alice

# set password aging policy
sudo chage -M 90 alice        # max 90 days
sudo chage -m 7 alice         # min 7 days between changes
sudo chage -W 7 alice         # warn 7 days before expiry
sudo chage -E 2025-12-31 alice # expire on date

# view password aging info
chage -l alice

# password quality: /etc/login.defs
# PASS_MAX_DAYS   90
# PASS_MIN_DAYS   7
# PASS_MIN_LEN    12
# PASS_WARN_AGE   7

# check password hash in /etc/shadow
sudo grep alice /etc/shadow

用户信息命令

whoami 显示当前用户名;id 显示 uid/gid/组。who 列出所有登录用户;w 添加他们正在运行什么。last 显示 /var/log/wtmp 中的登录历史;lastb 显示 /var/log/btmp 中的失败尝试。getent passwd 查询用户数据库(包括配置的 LDAP)。这些命令对系统管理和审计用户活动至关重要。

linux
# who am I
whoami                       # current username
id                           # uid, gid, groups
echo $USER                   # from environment

# who is logged in
who                          # all logged-in users
w                            # detailed (what they're doing)
users                        # just usernames

# last logins
last                         # recent logins
last -n 10                   # last 10 logins
last alice                   # alice's logins
last reboot                  # reboot history

# failed login attempts
lastb                       # bad login attempts (requires root)

# user account info
finger alice                 # detailed info (if installed)
getent passwd alice          # /etc/passwd entry

# group membership
groups                       # your groups
groups alice                 # alice's groups
id alice                     # uid, gid, all groups

# check if user exists
id alice && echo "exists" || echo "not found"
getent passwd alice

# list all users with home directories
getent passwd | awk -F: '{print $1, $6}'

su 与 sudo

su 切换用户(需要目标用户的密码);sudo 以 root 运行命令(需要你的密码)。su - 启动登录 shell(加载目标用户的配置文件)。sudo 更适合审计:命令记录在 /var/log/auth.log。visudo 安全地编辑 /etc/sudoers(保存前验证语法)。NOPASSWD 规则方便但降低安全性。sudo !! 以 root 重复上一条命令——经典的'忘记 sudo'修复法。

linux
# switch to root
su                           # needs root password
su -                         # login shell (loads root's profile)

# switch to another user
su - alice                   # login as alice
su alice                     # as alice, keep current env

# run a single command as root
sudo command
sudo apt update

# run a command as another user
sudo -u alice command
sudo -u www-data php script.php

# edit a file as root
sudo vim /etc/fstab
sudoedit /etc/fstab          # safer alternative

# sudo with environment
sudo -E command              # preserve environment variables

# list sudo privileges
sudo -l                      # what can I run?
sudo -l -U alice             # what can alice run?

# sudo configuration
sudo visudo                  # edit /etc/sudoers safely
# /etc/sudoers.d/ for individual rules
# alice ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx

# run previous command as root
sudo !!                      # classic fix for forgetting sudo

# sudo timeout: 5 min by default
sudo -v                      # extend timeout
sudo -k                      # kill timeout (require password next time)
10

进程管理

ps — 进程列表

ps 显示进程快照。aux(BSD)和 -ef(System V)是两种常见风格。'ps aux | grep' 模式无处不在(用 [n]ginx 技巧避免匹配 grep)。pstree 显示父子关系。--sort=-%mem 按内存使用排序(找资源占用者)。关键状态:R=运行,S=睡眠,D=不可中断睡眠,Z=僵尸,T=停止。实时监控用 top 或 htop。

linux
# list processes (BSD style)
ps aux                       # all processes, full format
ps aux | grep nginx          # find specific process

# list processes (System V style)
ps -ef                       # all processes
ps -ef | grep python

# list processes in a tree
ps auxf                      # forest/tree view
pstree                       # dedicated tree tool
pstree -p                    # with PIDs

# show specific user's processes
ps -u alice

# show process by PID
ps -p 1234
ps -p 1234 -o pid,ppid,cmd

# custom output format
ps -eo pid,ppid,user,%mem,%cpu,cmd --sort=-%mem | head

# show threads
ps -eLf | grep java          # show threads (LWP)

# ps output columns:
# PID    process ID
# PPID   parent process ID
# USER   owner
# %CPU   CPU usage
# %MEM   memory usage
# VSZ    virtual memory size (KB)
# RSS    resident set size (KB)
# STAT   process state (R=running, S=sleeping, Z=zombie)
# START  start time
# TIME   CPU time
# CMD    command

top 与 htop

top 是内置的实时进程监控器。关键命令:M(按内存排序),P(按 CPU 排序),k(杀死),q(退出)。-b(批处理)模式输出文本用于脚本。htop 是更优的替代品(彩色、可滚动、鼠标支持、树形视图)——用 apt install htop 安装。glances 提供全面的系统概览。查找资源消耗时,按 %CPU 或 %MEM 排序的 top/htop 是首选工具。

linux
# real-time process monitor
top

# top interactive commands:
#   P       sort by CPU usage
#   M       sort by memory usage
#   N       sort by PID
#   T       sort by running time
#   k       kill a process (enter PID)
#   r       renice (change priority)
#   1       show per-CPU stats
#   u       filter by user
#   H       show threads
#   c       toggle full command path
#   W       write settings to ~/.toprc
#   q       quit

# run top with specific sorting
top -o %MEM                  # sort by memory
top -o %CPU                  # sort by CPU

# batch mode (for scripts)
top -b -n 1                  # one snapshot
top -b -n 1 | head -20       # top 20 processes

# monitor specific user
top -u alice

# htop: better interactive viewer (install separately)
htop                         # colorized, mouse support
htop -p 1234                 # monitor specific PID

# glance: alternative system monitor
glances                      # needs installation

kill 与 killall

kill 按 PID 发送信号;killall/pkill 按名称发送。始终先尝试 SIGTERM(默认)——它允许优雅清理。SIGKILL (-9) 是强制和即时的;进程无法捕获,所以可能使资源处于不良状态。作为最后手段使用。pkill -f 匹配完整命令行。kill -l 列出所有信号。'kill; sleep; kill -9' 模式给进程一个清理机会再强制。

linux
# send signal to a process by PID
kill 12345                   # SIGTERM (graceful, default)
kill -15 12345               # SIGTERM explicitly
kill -9 12345                # SIGKILL (force, cannot be caught)
kill -HUP 12345              # SIGHUP (reload config)

# kill by name
killall nginx                # kill all nginx processes
pkill -f "python app.py"     # match full command line
pkill -u alice               # kill all of alice's processes

# common signals
kill -l                      # list all signals
# SIGTERM (15)  - graceful termination (default)
# SIGKILL (9)   - force kill (cannot be caught)
# SIGINT (2)    - interrupt (Ctrl+C)
# SIGHUP (1)    - hangup (often reload config)
# SIGSTOP (19)  - pause (cannot be caught)
# SIGCONT (18)  - resume
# SIGUSR1/USR2  - user-defined signals

# graceful then forceful
kill 12345; sleep 2; kill -9 12345 2>/dev/null

# kill background job
kill %1                      # kill job 1

# find and kill by port
fuser -k 8080/tcp            # kill process using port 8080
kill $(lsof -t -i:8080)      # alternative

后台作业与作业控制

追加 & 在后台运行。jobs 列出活动作业;fg/bg 在前台和后台间移动。Ctrl+Z 暂停前台作业。wait 阻塞直到后台作业完成。nohup 和 disown 都防止进程在终端关闭时死亡——nohup 用于新命令,disown 用于已运行的命令。持久工作请使用 tmux 或 screen。

linux
# run in background (append &)
sleep 100 &
# [1] 12345   (job 1, PID 12345)

# list jobs
jobs
jobs -l                      # with PIDs

# bring to foreground / send to background
fg                           # foreground the current job
fg %1                        # foreground job 1
bg %2                        # background job 2

# Ctrl+Z: suspend foreground job, then resume in background
# Ctrl+Z sends SIGTSTP
bg                           # resume in background

# wait for background jobs
wait                         # wait for all
wait $!                      # wait for last background job
wait 12345                   # wait for specific PID

# disown: detach from shell (survives logout)
long_task &
disown %1

# nohup: run immune to hangups (survives logout)
nohup ./script.sh > output.log 2>&1 &

# run at lower priority
nice -n 10 ./backup.sh &

# parallel execution
cmd1 & cmd2 & cmd3 &
wait                         # wait for all to finish

nice 与 renice — 进程优先级

nice 值范围从 -20(最高优先级)到 19(最低)。普通用户只能降低优先级(正值);root 可以提高(负值)。默认为 0。nice 以特定优先级启动进程;renice 更改正在运行的进程。对于 I/O 密集型任务,ionice 控制磁盘 I/O 优先级(类:1=实时,2=最佳努力,3=空闲)。cpulimit 限制 CPU 使用——适合不应干扰的后台任务。

linux
# nice: start a process with adjusted priority
nice ./script.sh             # default: +10 (lower priority)
nice -n 10 ./backup.sh       # priority 10 (lower)
nice -n -5 ./critical.sh     # higher priority (needs root)

# renice: change priority of running process
renice 5 -p 12345            # PID 12345 to priority 5
renice 10 -u alice           # all of alice's processes
renice -5 -p 12345           # higher priority (needs root)

# view priorities
ps -l                        # NI column shows nice value
top                          # NI column

# nice values:
#  -20  highest priority (most favorable)
#    0  default
#   19  lowest priority (least favorable)
# only root can set negative (higher) priority

# practical: run CPU-intensive task at low priority
nice -n 19 make -j4 &

# ionice: I/O priority
ionice -c 3 ./backup.sh      # idle I/O priority
ionice -c 2 -n 7 ./backup.sh # best-effort, low

# cpulimit: limit CPU usage (install separately)
cpulimit -p 12345 -l 50      # limit to 50% CPU

/proc 文件系统

/proc 是虚拟文件系统(不占磁盘存储),暴露内核和进程信息。/proc/PID/ 包含每个进程的数据。/proc/cpuinfo、/proc/meminfo 显示硬件信息。/proc/sys/ 包含可调内核参数(等同于 sysctl)。写入 /proc/sys/ 立即更改内核设置(但用 sysctl 持久化)。/proc/mounts 显示当前挂载的文件系统。这是用户空间和内核之间的主要接口。

linux
# /proc: virtual filesystem with kernel/process info
# process info by PID
cat /proc/1234/status        # process status
cat /proc/1234/cmdline       # command line (null-separated)
ls -l /proc/1234/fd/         # open file descriptors
cat /proc/1234/environ       # environment variables (null-separated)

# system info
cat /proc/cpuinfo            # CPU information
cat /proc/meminfo            # memory information
cat /proc/version            # kernel version
cat /proc/uptime             # uptime in seconds
cat /proc/loadavg            # load average

# network info
cat /proc/net/tcp            # TCP connections
cat /proc/net/dev            # network interface stats

# kernel settings
ls /proc/sys/                # sysctl parameters
cat /proc/sys/net/ipv4/ip_forward
echo 1 > /proc/sys/net/ipv4/ip_forward  # enable IP forwarding

# mount info
cat /proc/mounts             # mounted filesystems
cat /proc/filesystems        # supported filesystem types

# view process memory maps
cat /proc/1234/maps          # memory mappings
pmap 1234                    # formatted version
11

系统信息

uname 与 hostname

uname 显示内核信息(-a 显示全部)。hostname 显示/设置系统名称——hostnamectl set-hostname 使其持久化。/etc/os-release 是识别发行版的标准方式(在所有现代 Linux 上有效)。lscpu 给出详细的 CPU 架构信息。dmidecode 读取 BIOS/SMBIOS 数据。这些命令是任何系统管理任务的第一步,了解你在处理什么。

linux
# kernel and system info
uname                        # kernel name: Linux
uname -a                     # all info
uname -r                     # kernel release: 5.15.0-91-generic
uname -m                     # machine hardware: x86_64
uname -n                     # network node (hostname)
uname -p                     # processor type
uname -o                     # operating system: GNU/Linux

# hostname
hostname                     # current hostname
hostname -f                  # fully qualified domain name
hostname -I                  # all IP addresses

# set hostname (persistent)
sudo hostnamectl set-hostname myserver

# distribution info
cat /etc/os-release          # distro name and version
lsb_release -a               # Ubuntu/Debian specific
cat /etc/debian_version      # Debian version

# kernel version
cat /proc/version
dmesg | grep "Linux version"

# system architecture
arch                         # e.g., x86_64
dpkg --print-architecture    # Debian/Ubuntu

# BIOS/hardware info
sudo dmidecode -t system     # system info
sudo dmidecode -t bios       # BIOS info
lshw                         # hardware list
lscpu                        # CPU details

df — 磁盘剩余空间

df 报告文件系统磁盘空间。-h(人类可读)必不可少。-T 显示文件系统类型(ext4、xfs、btrfs、tmpfs、nfs)。-i 显示 inode 使用——可能在空间用完前用完 inode(大量小文件时常见)。-x 排除文件系统类型(用于过滤 tmpfs 等虚拟文件系统)。磁盘满时,先检查 df -h,再用 du 找到占用空间的目录。

linux
# show disk space for all filesystems
df                           # all mounted filesystems
df -h                        # human-readable (K, M, G)
df -H                        # SI units (KB, MB, GB)

# specific filesystem
df -h /home                  # space for /home
df -h /dev/sda1              # specific device

# filesystem type
df -T                        # show type (ext4, xfs, tmpfs, etc.)
df -Th                       # human-readable + type

# exclude specific types
df -x tmpfs -x devtmpfs      # exclude virtual filesystems

# inodes (file count limit)
df -i                        # inode usage
df -ih                       # human-readable inode usage

# local filesystems only
df -l

# show total
df -h --total

# find the filesystem using the most space
df -h | sort -rh -k5 | head

# real-time: watch disk space
watch -n 5 df -h

du — 磁盘使用量

du 测量磁盘使用量。-s(摘要)只显示总计;-h 人类可读。du -sh */ 显示直接子目录大小。sort -rh 按人类可读值排序。--apparent-size 显示逻辑文件大小 vs 实际磁盘块。--exclude 跳过模式。查找磁盘空间消耗的工作流是:df -h(哪个文件系统满了)→ du -sh *(哪个目录)→ find(哪些文件)。

linux
# size of current directory
du -sh .

# size of specific directories
du -sh /var/log /tmp /home

# size of all immediate subdirectories
du -sh */
du -sh * | sort -rh          # sorted largest first

# top 10 largest directories
du -sh * | sort -rh | head -10

# maximum depth
du -h -d 1                   # depth 1 only
du -h --max-depth=2

# include hidden files
du -sh .[!.]*

# apparent size (logical, not disk blocks)
du -sh --apparent-size file

# exclude patterns
du -sh --exclude='*.log' .
du -sh --exclude=node_modules .

# total of multiple directories
du -sh /var/log /var/lib /tmp | tail -1

# find largest files (not just directories)
find / -type f -exec ls -lhS {} + 2>/dev/null | head -10
find . -type f -printf '%s %p\n' | sort -rn | head -10

# sort all subdirectories by size
du -sh ./*/* | sort -rh | head -20

free — 内存使用

free 显示内存使用。'available' 列最有意义——它估计有多少内存可用于启动新应用而不需要交换。Linux 有意将空闲 RAM 用作缓存(buff/cache)以加速磁盘读取;这会按需回收,所以低 'free' 是正常的。Swap 使用量应被监控——高 swap 使用伴有活跃交换(vmstat 中的 si/so)表示内存压力。

linux
# show memory usage
free                         # in KB
free -h                      # human-readable
free -m                      # in MB
free -g                      # in GB

# continuous update
free -h -s 1                 # update every 1 second
watch -n 1 free -h           # alternative

# output:
#               total   used   free   shared  buff/cache  available
# Mem:           16G     4G     2G     0.5G       10G          11G
# Swap:          8G      0G     8G

# detailed memory info
cat /proc/meminfo

# key fields:
# total       total RAM
# used        used by applications
# free        completely free
# buff/cache  kernel buffers and page cache
# available   estimate of memory available for new apps

# IMPORTANT: Linux uses free RAM for cache
# 'available' is more meaningful than 'free'
# Cache is reclaimed on demand, so don't panic if 'free' is low

# swap info
swapon --show                # show swap devices
cat /proc/swaps

# clear cache (requires root, use with caution)
sudo sysctl vm.drop_caches=3   # free pagecache, dentries, inodes

# process memory usage
ps aux --sort=-%mem | head -10  # top memory consumers

uptime 与系统负载

uptime 显示系统运行时间和负载均值(1/5/15 分钟平均值)。负载均值表示等待 CPU 的平均进程数——通常应低于 CPU 核心数。vmstat 显示实时 CPU、内存和 I/O 统计——'r' 列(可运行进程)和 'si/so'(swap 进/出)是关键指标。iostat 和 sar(来自 sysstat 包)提供详细的 I/O 和历史数据。

linux
# system uptime and load average
uptime
# 10:30:00 up 5 days,  3:21,  2 users,  load average: 0.50, 0.35, 0.25

# load average: 1min, 5min, 15min
#   = average number of processes waiting for CPU
#   rule of thumb: should be < number of CPU cores

# check CPU count
nproc                         # number of CPU cores
lscpu | grep "^CPU(s):"

# detailed load and context switches
cat /proc/loadavg
# 0.50 0.35 0.25 2/500 12345

# vmstat: system stats over time
vmstat 1 5                    # every 1 second, 5 times
# procs --memory-- ---swap-- -----io---- -system-- ------cpu-----
# r  b   swpd   free   buff  cache  si  so    bi    bo   in   cs us sy id wa

# iostat: I/O statistics (needs sysstat package)
iostat 1                      # every 1 second
iostat -x 1                   # extended stats

# mpstat: per-CPU statistics
mpstat -P ALL 1

# sar: historical system activity
sar -u                        # CPU usage history
sar -r                        # memory usage history

# who is logged in
who
w                             # with what they're doing
12

网络

ping 与 traceroute

ping 使用 ICMP echo 测试可达性并测量延迟。-c 限制次数(否则永远运行)。traceroute 显示到目标的每一跳——用于诊断连接在哪里失败。mtr 结合 traceroute 和持续 ping(非常适合诊断间歇性问题)。dig 查询 DNS 记录(比 nslookup 更详细)。nc(netcat)-z 测试 TCP 端口是否开放而不发送数据。

linux
# test connectivity
ping google.com
ping -c 4 google.com         # 4 packets then stop
ping -i 0.5 google.com       # 0.5s interval
ping -W 2 google.com         # 2s timeout per packet

# ping with timestamp
ping -D google.com           # unix timestamps

# check if host is reachable
ping -c 1 -W 1 host && echo "up" || echo "down"

# trace network path
traceroute google.com
traceroute -n google.com     # no DNS resolution (faster)
mtr google.com               # traceroute + ping (continuous)

# trace with TCP (bypasses ICMP blocking)
tcptraceroute google.com 443

# DNS lookup
dig example.com
dig +short example.com       # just the IP
dig MX example.com           # mail records
dig NS example.com           # name servers
dig @8.8.8.8 example.com     # specific DNS server

# alternative DNS tools
nslookup example.com
host example.com
host -t MX example.com

# check open ports
nc -zv google.com 443        # check if port 443 is open
nc -zv google.com 80 443 22  # check multiple ports

netstat 与 ss

ss 是 netstat 的现代替代品——更快更详细。-tlnp 显示监听 TCP 端口和进程名(-p 需要 root)。查找占用端口的进程:ss -tlnp | grep :PORT 或 lsof -i :PORT。ip 替代 ifconfig/route(来自 iproute2 包)。关键:-n 阻止 DNS 解析(快得多)。检查 'state established' 查看活动连接。netstat 已弃用但仍广泛可用。

linux
# ss: modern socket statistics (replaces netstat)
ss -tlnp                     # listening TCP ports + process
ss -tunap                    # all TCP/UDP connections
ss -s                        # socket summary

# netstat: classic network statistics
netstat -tlnp                # listening TCP ports
netstat -tunap               # all connections
netstat -rn                  # routing table
netstat -i                   # interface statistics

# common ss/netstat flags:
# -t  TCP
# -u  UDP
# -l  listening sockets only
# -n  numeric (no DNS resolution, faster)
# -a  all sockets
# -p  show process using socket (needs root)
# -r  routing table

# find what's listening on a port
ss -tlnp | grep :80
lsof -i :8080                # alternative

# check established connections
ss -tn state established

# show all connections to a specific host
ss -tn dst google.com

# view network interfaces
ip addr                      # modern
ip a                         # short form
ifconfig                     # legacy

# view routing table
ip route                     # modern
route -n                     # legacy

# view interface statistics
ip -s link
ifconfig eth0

curl — HTTP 客户端

curl 是命令行必备的 HTTP 客户端。-X 设置方法;-d 发送 POST 数据;-H 设置头;-L 跟随重定向;-O 以远程文件名保存;-s 静默(用于脚本);-w '%{http_code}' 只提取状态码。对于 JSON API,结合 -H 'Content-Type: application/json' 和 -d。-u 提供基本认证。REST API 测试中,curl 是通用标准。

linux
# basic GET request
curl https://api.example.com/data

# save to file
curl -O https://example.com/file.zip     # save with remote filename
curl -o file.zip https://example.com/file.zip  # custom name

# follow redirects
curl -L https://short.url/abc

# HTTP methods
curl -X POST https://api.example.com/users
curl -X PUT -d '{"name":"Alice"}' https://api.example.com/users/1
curl -X DELETE https://api.example.com/users/1

# send data
curl -d "name=Alice&age=30" https://api.example.com/form
curl -H "Content-Type: application/json" \
     -d '{"name":"Alice"}' https://api.example.com/users

# headers
curl -H "Authorization: Bearer TOKEN" \
     -H "Accept: application/json" \
     https://api.example.com/data

# verbose / headers only
curl -v https://example.com                # verbose
curl -I https://example.com                # headers only

# authentication
curl -u user:pass https://api.example.com  # basic auth
curl --netrc-file ~/.netrc https://...     # netrc

# download with progress bar
curl --progress-bar -O https://example.com/largefile.iso

# get HTTP status code only
curl -s -o /dev/null -w "%{http_code}" https://example.com

# retry on failure
curl --retry 3 --retry-delay 5 https://example.com

# pass query parameters
curl "https://api.example.com/search?q=linux&page=2"

wget — 下载文件

wget 非交互式下载文件。-c 恢复中断的下载(大文件必不可少)。-m 镜像网站(-k 转换链接)。-r 递归,-l 限制深度。-i 从文件读取 URL。wget 在递归/镜像下载和恢复方面优于 curl——curl 用 -C - 恢复。--limit-rate 限制带宽。wget 自动处理重定向和 cookie。

linux
# download a file
wget https://example.com/file.zip

# download with custom name
wget -O myfile.zip https://example.com/file.zip

# download in background
wget -b https://example.com/largefile.iso

# resume interrupted download
wget -c https://example.com/largefile.iso

# mirror a website
wget -m https://example.com
wget -m -k -K -E https://example.com  # convert links for local viewing

# recursive download (limited depth)
wget -r -l 2 https://example.com

# download all files of a type
wget -r -A pdf https://example.com/documents/

# continue and retry
wget -t 5 --waitretry=10 https://example.com/file.zip

# quiet mode (no output)
wget -q https://example.com/file.zip

# download from a list of URLs
wget -i urls.txt

# authentication
wget --user=user --password=pass https://example.com/protected

# set user agent
wget --user-agent="Mozilla/5.0" https://example.com

# limit download speed
wget --limit-rate=200k https://example.com/file.zip

# ignore certificate errors
wget --no-check-certificate https://example.com/file.zip

ip 与 ifconfig

ip(来自 iproute2)是 ifconfig/route 的现代替代品。ip a 显示地址;ip link 显示二层信息;ip route 显示路由表。用 ip 的更改是临时的(重启后丢失)——持久化需编辑 /etc/netplan/(Ubuntu)、/etc/network/interfaces(Debian)或使用 nmcli(NetworkManager)。ifconfig 已弃用但仍广泛使用。无线网络用 iw/iwconfig。

linux
# view network interfaces (modern)
ip addr show                  # all interfaces
ip a                          # short form
ip a show eth0                # specific interface

# view link status
ip link show
ip -s link show eth0          # with statistics

# bring interface up/down
sudo ip link set eth0 up
sudo ip link set eth0 down

# assign IP address
sudo ip addr add 192.168.1.100/24 dev eth0
sudo ip addr del 192.168.1.100/24 dev eth0

# routing table
ip route show
ip route                      # short form
sudo ip route add default via 192.168.1.1

# view ARP table
ip neigh                      # neighbors (ARP)
arp -a                        # legacy

# DNS configuration
cat /etc/resolv.conf

# ifconfig (legacy, still common)
ifconfig                      # all interfaces
ifconfig eth0                 # specific interface
sudo ifconfig eth0 192.168.1.100 netmask 255.255.255.0 up

# change MAC address
sudo ip link set dev eth0 address 00:11:22:33:44:55

# view wireless info
iwconfig                      # wireless interfaces
iw list                       # wireless capabilities

# network manager (desktop)
nmcli device status
nmcli connection show

DNS 查询 (dig, nslookup)

dig 是最强大的 DNS 查询工具。+short 给出简洁输出。常见记录类型:A(IPv4),AAAA(IPv6),MX(邮件),NS(名称服务器),TXT(文本/SPF),CNAME(别名)。@server 查询特定 DNS 服务器。-x 做反向查询(IP 到主机名)。+trace 显示从根服务器的完整解析路径。host 是更简单的替代。DNS 传播检查比较多个服务器的结果。

linux
# dig: detailed DNS lookup
dig example.com
dig +short example.com        # just the IP address
dig example.com A             # A record (IPv4)
dig example.com AAAA          # AAAA record (IPv6)
dig example.com MX            # mail exchange
dig example.com NS            # name servers
dig example.com TXT           # TXT records (SPF, etc.)
dig example.com SOA           # start of authority

# query specific DNS server
dig @8.8.8.8 example.com
dig @1.1.1.1 example.com MX

# reverse DNS lookup
dig -x 1.2.3.4
dig -x 8.8.8.8 +short

# trace DNS resolution path
dig +trace example.com

# JSON output (for scripting)
dig +json example.com

# nslookup: simpler alternative
nslookup example.com
nslookup example.com 8.8.8.8   # use specific server

# host: concise output
host example.com               # IP address
host -t MX example.com        # mail records
host -t NS example.com        # name servers
host 8.8.8.8                   # reverse lookup

# check DNS propagation
# compare results from multiple servers
for dns in 8.8.8.8 1.1.1.1 9.9.9.9; do
    echo "=== $dns ==="
    dig @$dns example.com +short
done

# flush DNS cache
sudo systemd-resolve --flush-caches   # systemd
sudo resolvectl flush-caches          # newer systemd
13

包管理

apt (Debian/Ubuntu)

apt 是 dpkg/apt-get 的用户友好前端(Debian/Ubuntu)。安装/升级前始终运行 apt update 刷新包列表。upgrade 保留包;full-upgrade 可能移除包以解决依赖。purge 移除配置文件。autoremove 清理孤立的依赖。dpkg -S 查找哪个包拥有某个文件。apt-mark hold 防止包被升级(用于固定版本)。

linux
# update package list
sudo apt update

# upgrade installed packages
sudo apt upgrade             # upgrade without removing
sudo apt full-upgrade        # upgrade, may remove packages
sudo apt dist-upgrade        # alias for full-upgrade

# install packages
sudo apt install nginx
sudo apt install nginx=1.18* # specific version
sudo apt install -y nginx    # no prompt

# remove packages
sudo apt remove nginx        # remove but keep config
sudo apt purge nginx         # remove including config
sudo apt autoremove          # remove unused dependencies
sudo apt clean               # clean downloaded packages

# search for packages
apt search nginx
apt-cache search web server

# show package info
apt show nginx
apt-cache policy nginx       # available versions

# list installed packages
apt list --installed
dpkg -l | grep nginx

# list files installed by a package
dpkg -L nginx
dpkg -S /usr/bin/curl        # which package owns a file

# add PPA (Ubuntu)
sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt update

# hold package (prevent upgrade)
sudo apt-mark hold nginx
sudo apt-mark unhold nginx

dnf/yum (RHEL/Fedora/CentOS)

dnf 在现代 Fedora/RHEL/CentOS 8+ 上替代 yum。命令类似。dnf provides(或 yum provides)查找哪个包提供某个文件——查找缺失依赖的关键。rpm -ql 列出已安装包中的文件;rpm -qf 查找文件的所有者。EPEL 为 RHEL/CentOS 提供额外包。dnf groupinstall 安装包组(如 Development Tools)。yum 在许多系统上仍是 dnf 的符号链接。

linux
# dnf: modern Fedora/RHEL/CentOS
sudo dnf install nginx
sudo dnf update              # update all packages
sudo dnf upgrade             # same as update
sudo dnf remove nginx

# search
dnf search nginx
dnf list available           # all available packages
dnf list installed           # installed packages

# package info
dnf info nginx
dnf provides /usr/bin/curl   # which package provides a file

# clean cache
sudo dnf clean all

# group install
dnf groupinstall "Development Tools"
dnf group list

# yum: older CentOS/RHEL (still available)
sudo yum install nginx
sudo yum update
sudo yum remove nginx
yum search nginx
yum provides /usr/bin/curl

# enable EPEL repository (Extra Packages for Enterprise Linux)
sudo dnf install epel-release

# list dependencies
dnf repoquery --requires nginx
dnf repoquery --deplist nginx

# downgrade a package
sudo dnf downgrade nginx

# view package files
rpm -ql nginx                # files installed by package
rpm -qi nginx                # package info
rpm -qf /usr/bin/curl        # which package owns file

pacman (Arch Linux)

pacman 是 Arch Linux 的包管理器。-Syu 是重要的系统更新命令(始终全系统更新,绝不部分更新)。-S 安装,-R 移除,-Q 查询本地。-Rs 移除并清理未使用的依赖;-Rns 还移除配置。Arch 是滚动发行版——部分升级不受支持且可能破坏系统。AUR(Arch User Repository)通过 yay/paru 等助手提供社区包。

linux
# update system
sudo pacman -Syu            # sync repos + upgrade all
# ALWAYS update the full system on Arch

# install packages
sudo pacman -S nginx
sudo pacman -S --needed nginx  # don't reinstall if up to date

# remove packages
sudo pacman -R nginx         # remove package only
sudo pacman -Rs nginx        # remove + unused deps
sudo pacman -Rns nginx       # remove + deps + config

# search packages
pacman -Ss nginx             # search repos
pacman -Qs nginx             # search installed

# package info
pacman -Si nginx             # info from repos
pacman -Qi nginx             # info from installed
pacman -Ql nginx             # list files
pacman -Qo /usr/bin/curl     # which package owns file

# list orphaned packages
pacman -Qdt

# clean cache
sudo pacman -Sc             # clean old packages
sudo pacman -Scc            # clean all cache

# query local database
pacman -Q                   # all installed packages
pacman -Qe                  # explicitly installed
pacman -Qm                  # foreign (AUR) packages

# AUR (Arch User Repository)
# install yay or paru for AUR support
yay -S package-name         # install from AUR

# downgrade a package
sudo pacman -U /var/cache/pacman/pkg/package-1.0-1.x86_64.pkg.tar.zst

查找包

通过关键字查找包(apt/dnf search)或通过文件查找(apt-file/dnf provides/pacman -F)在遇到 'command not found' 时至关重要。'哪个包拥有此文件'查询(dpkg -S / rpm -qf / pacman -Qo)对理解已安装内容非常有价值。apt-file(Debian)和 pacman -F(Arch)搜索尚未安装的包的文件数据库——用于查找哪个包提供所需的头文件或库。

linux
# Debian/Ubuntu
apt search keyword
apt-cache search keyword
apt list --installed | grep keyword

# RHEL/Fedora
dnf search keyword
yum search keyword

# Arch
pacman -Ss keyword

# search by file name/path
# Debian: apt-file (separate package)
sudo apt install apt-file
sudo apt-file update
apt-file find /usr/bin/curl
apt-file search curl.h

# RHEL/Fedora
dnf provides /usr/bin/curl
dnf provides *curl.h
yum whatprovides /usr/bin/curl

# Arch
pacman -F /usr/bin/curl
pacman -Fy                  # update file database first

# check if package is installed
dpkg -l | grep nginx         # Debian
rpm -q nginx                 # RHEL
pacman -Q nginx              # Arch

# list files installed by a package
dpkg -L nginx                # Debian
rpm -ql nginx                # RHEL
pacman -Ql nginx             # Arch

# find which package owns a file
dpkg -S /usr/bin/curl         # Debian
rpm -qf /usr/bin/curl         # RHEL
pacman -Qo /usr/bin/curl      # Arch

# show package dependencies
apt-cache depends nginx      # Debian
dnf repoquery --requires nginx  # RHEL
pacman -Si nginx             # Arch

仓库管理

仓库是包源。在 Debian/Ubuntu 上,PPA(个人包档案)提供第三方软件——始终添加签名密钥以验证包。/etc/apt/sources.list.d/ 存放自定义仓库文件。在 RHEL/Fedora 上,dnf config-manager 管理仓库;EPEL 对 RHEL 至关重要。在 Arch 上,编辑 /etc/pacman.conf。始终验证 GPG 密钥以防安装恶意包。apt policy 和 dnf repolist 显示已配置的仓库。

linux
# Debian/Ubuntu: add repository
sudo add-apt-repository ppa:deadsnakes/ppa
sudo add-apt-repository "deb https://packages.example.com/ubuntu jammy main"

# remove repository
sudo add-apt-repository --remove ppa:deadsnakes/ppa

# add repository manually
echo "deb https://packages.example.com/ubuntu jammy main" | \
    sudo tee /etc/apt/sources.list.d/example.list

# add signing key (Debian)
wget -qO- https://example.com/key.gpg | \
    sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/example.gpg

# list repositories
apt policy                   # show configured repos
grep -r "" /etc/apt/sources.list.d/

# RHEL/Fedora: enable repository
sudo dnf config-manager --add-repo https://example.com/repo.repo
sudo dnf install epel-release  # enable EPEL
sudo dnf repolist              # list enabled repos
sudo dnf repolist all          # list all repos

# enable/disable a repo
sudo dnf config-manager --set-enabled epel
sudo dnf config-manager --set-disabled epel

# Arch: edit /etc/pacman.conf
# [custom]
# Server = https://example.com/$repo/os/$arch

# verify package integrity
dpkg --verify                 # Debian
rpm -Va                       # RHEL
14

服务管理 (systemd)

服务控制

systemctl 管理 systemd 服务。start/stop/restart 是基本操作。reload 发送信号重新读取配置而不完全重启(优雅)。status 显示当前状态和最近日志。mask 完全阻止服务被启动(甚至手动)——比 disable 更强。is-active 和 is-enabled 对脚本有用(活动/启用时返回 0)。

linux
# start/stop/restart services
sudo systemctl start nginx
sudo systemctl stop nginx
sudo systemctl restart nginx
sudo systemctl reload nginx    # reload config without restart

# try-restart (only if running)
sudo systemctl try-restart nginx

# reload or restart (reload if possible, otherwise restart)
sudo systemctl reload-or-restart nginx

# send signal to service
sudo systemctl kill nginx
sudo systemctl kill -s HUP nginx

# check service status
sudo systemctl status nginx
systemctl is-active nginx       # active/inactive
systemctl is-enabled nginx      # enabled/disabled
systemctl is-failed nginx       # failed/running

# show service logs (recent)
sudo systemctl status nginx

# mask a service (prevent from starting)
sudo systemctl mask nginx
sudo systemctl unmask nginx

# reset failed state
sudo systemctl reset-failed

# emergency: reboot/poweroff
sudo systemctl reboot
sudo systemctl poweroff
sudo systemctl halt
sudo systemctl suspend

服务状态与详情

systemctl status 提供综合视图:状态、PID、内存/CPU 使用和最近日志。systemctl cat 显示单元文件(包括覆盖)。systemctl edit 创建 drop-in 覆盖文件而不修改原始文件——安全地自定义供应商提供的服务。编辑单元文件后,运行 daemon-reload 通知 systemd 更改。list-dependencies 显示服务依赖什么。

linux
# detailed status
systemctl status nginx
# Shows: loaded state, active state, recent log entries, cgroup info

# just the active state
systemctl is-active nginx       # "active" or "inactive"

# is it enabled at boot?
systemctl is-enabled nginx      # "enabled" or "disabled"

# check if service failed
systemctl is-failed nginx

# list dependencies
systemctl list-dependencies nginx

# show service file
systemctl cat nginx
systemctl cat nginx.service

# show service properties
systemctl show nginx
systemctl show -p ExecStart nginx

# view service file location
systemctl show -p FragmentPath nginx

# edit service file (override)
sudo systemctl edit nginx       # creates override file
sudo systemctl edit --full nginx  # edit full unit file

# reload systemd after editing unit files
sudo systemctl daemon-reload

# list sockets
systemctl list-sockets

# check all failed services
systemctl --failed

启用/禁用服务

enable 使服务开机启动(创建符号链接);disable 移除符号链接。--now 结合 enable/disable 与 start/stop。list-unit-files 显示所有可用服务(已安装但可能未运行);list-units 显示已加载/活动的。默认目标(multi-user = 文本模式,graphical = GUI)替代传统运行级别。使用 --state= 按状态过滤。

linux
# enable service to start at boot
sudo systemctl enable nginx

# enable and start in one command
sudo systemctl enable --now nginx

# disable (don't start at boot)
sudo systemctl disable nginx

# disable and stop in one command
sudo systemctl disable --now nginx

# re-enable (apply symlink changes)
sudo systemctl reenable nginx

# check if enabled
systemctl is-enabled nginx

# list enabled services
systemctl list-unit-files --state=enabled

# list all service unit files
systemctl list-unit-files --type=service

# list running services
systemctl list-units --type=service --state=running

# list all loaded services
systemctl list-units --type=service

# list services by state
systemctl list-units --type=service --state=failed
systemctl list-units --type=service --state=exited

# default boot target
systemctl get-default          # usually graphical.target or multi-user.target

# change boot target
sudo systemctl set-default multi-user.target  # text mode (runlevel 3)
sudo systemctl set-default graphical.target    # GUI mode (runlevel 5)

列出与过滤服务

list-units 显示当前加载到内存的;list-unit-files 显示磁盘上已安装的。--type 按单元类型过滤(service、socket、timer、mount、target)。--state 按状态过滤(running、exited、failed、enabled、disabled)。计时器(systemd timer)是 cron 作业的 systemd 原生替代——支持基于依赖的调度,通过 list-timers 查看。--reverse 显示什么依赖于某个单元。

linux
# list all active units
systemctl list-units

# list only services
systemctl list-units --type=service

# list by state
systemctl list-units --type=service --state=running
systemctl list-units --type=service --state=exited
systemctl list-units --type=service --state=failed

# list all unit files (installed)
systemctl list-unit-files --type=service

# list by state (unit files)
systemctl list-unit-files --state=enabled
systemctl list-unit-files --state=disabled
systemctl list-unit-files --state=masked

# list by target (runlevel)
systemctl list-units --type=target

# list sockets
systemctl list-units --type=socket
systemctl list-sockets

# list timers (replaces cron for many tasks)
systemctl list-timers
systemctl list-timers --all

# list mounts
systemctl list-units --type=mount

# show all units (including inactive)
systemctl list-units --all

# show specific unit type
systemctl list-units --type=service --all

# count services by state
systemctl list-units --type=service --no-legend | wc -l
systemctl list-units --type=service --state=running --no-legend | wc -l

# find services that depend on a unit
systemctl list-dependencies --reverse nginx

journalctl — 系统日志

journalctl 查询 systemd 日志(结构化日志)。-f 实时跟随。-u 按单元(服务)过滤。-b 按启动过滤(-b -1 = 上次启动)。--since/--until 使用灵活的时间表达式。-p 按优先级过滤(emerg 到 debug)。日志在重启后持久(存储在 /var/log/journal/)。--vacuum-time 和 --vacuum-size 控制磁盘使用。journalctl 替代 systemd 系统的 /var/log/messages。

linux
# view all logs (newest last)
journalctl

# follow logs (like tail -f)
journalctl -f

# today's logs
journalctl --since today
journalctl -u nginx --since today

# specific time range
journalctl --since "2024-01-01" --until "2024-01-02"
journalctl --since "1 hour ago"
journalctl --since "30 min ago"

# logs for a specific service
journalctl -u nginx
journalctl -u nginx -f          # follow
journalctl -u nginx --since "1 hour ago"

# logs for current boot
journalctl -b                   # current boot
journalctl -b -1                # previous boot
journalctl --list-boots         # list all boots

# filter by priority
journalctl -p err               # errors only
journalctl -p warning           # warnings and above
# 0=emerg, 1=alert, 2=crit, 3=err, 4=warning, 5=notice, 6=info, 7=debug

# filter by process
journalctl _PID=1234
journalctl _UID=1000

# show kernel messages only
journalctl -k

# output format
journalctl -o json              # JSON format
journalctl -o short-iso         # ISO timestamps
journalctl --no-pager           # no pager (for scripts)

# clear old logs
sudo journalctl --vacuum-time=7d    # keep last 7 days
sudo journalctl --vacuum-size=100M  # keep 100MB max
15

定时任务 (Cron)

crontab 基础

crontab -e 编辑你的定时任务。格式:分钟 小时 日 月 周 命令。* 表示'每'。*/N 表示'每 N'。Cron 在最小化环境中运行——始终对命令和脚本使用绝对路径。脚本应显式设置 PATH。输出通过邮件发送给用户(在 crontab 中配置 MAILTO)或重定向到日志文件。系统级任务放在 /etc/crontab 或 /etc/cron.*/ 目录中。

linux
# edit your crontab
crontab -e

# list your crontab entries
crontab -l

# remove all crontab entries
crontab -r

# edit another user's crontab (requires root)
sudo crontab -u alice -e
sudo crontab -u alice -l

# crontab entry format:
# minute hour day-of-month month day-of-week command
# 0-59   0-23 1-31          1-12  0-6 (0=Sunday)
#
# *  *  *  *  *  command to execute
# |  |  |  |  |
# |  |  |  |  +----- day of week (0-7) (0 or 7 is Sunday)
# |  |  |  +------- month (1-12)
# |  |  +--------- day of month (1-31)
# |  +----------- hour (0-23)
# +------------- minute (0-59)

# examples:
# run every day at 2:30 AM
30 2 * * * /home/user/backup.sh

# run every Monday at 9 AM
0 9 * * 1 /home/user/weekly-report.sh

# run every 15 minutes
*/15 * * * * /home/user/check.sh

# run at reboot
@reboot /home/user/startup.sh

# system-wide cron: /etc/crontab
# adds a user column:
# minute hour day month week USER command
*/30 * * * * root /usr/local/bin/check.sh

# cron directories (run all scripts inside)
/etc/cron.daily/    # daily
/etc/cron.hourly/   # hourly
/etc/cron.weekly/   # weekly
/etc/cron.monthly/  # monthly

Cron 调度语法

Cron 使用 5 个字段:分钟(0-59),小时(0-23),日(1-31),月(1-12),周(0-7,0 和 7 都是周日)。* 表示每;*/N 表示每 N;逗号分隔值;短横线定义范围。周和日同时指定时是 OR 关系(非 AND)。月末技巧检查明天是否是 1 号。部署真实任务前始终用简单 echo 测试 cron 调度。

linux
# every minute
* * * * * command

# every 5 minutes
*/5 * * * * command

# every hour at minute 0
0 * * * * command

# every day at midnight
0 0 * * * command

# every day at 2:30 AM
30 2 * * * command

# every Monday at 8 AM
0 8 * * 1 command

# every weekday (Mon-Fri) at 9 AM
0 9 * * 1-5 command

# every weekend (Sat and Sun) at 10 AM
0 10 * * 0,6 command

# every month on the 1st at midnight
0 0 1 * * command

# every quarter (Jan, Apr, Jul, Oct) on the 1st
0 0 1 1,4,7,10 * command

# every 15 minutes during business hours
*/15 9-17 * * 1-5 command

# twice a day (midnight and noon)
0 0,12 * * * command

# every 2 hours
0 */2 * * * command

# last day of month (tricky — use date check)
0 0 28-31 * * [ "$(date +%d -d tomorrow)" = "01" ] && /script.sh

# run on specific date (Jan 1 at midnight)
0 0 1 1 * command

特殊 Cron 字符串

特殊字符串(@daily、@weekly 等)是常用调度的简写——比 5 字段格式更可读。@reboot 在系统启动时运行一次。MAILTO 控制输出发送到哪里——设为空以禁用。Cron 使用最小化环境(有限 PATH,无 shell 配置)——始终显式设置 PATH 或使用绝对路径。输出重定向至关重要:没有它,输出被邮件发送或丢失。

linux
# predefined special strings (GNU cron)
@reboot     command    # run once at startup
@yearly     command    # once a year: 0 0 1 1 *
@annually   command    # same as @yearly
@monthly    command    # once a month: 0 0 1 * *
@weekly     command    # once a week: 0 0 * * 0
@daily      command    # once a day: 0 0 * * *
@midnight   command    # same as @daily
@hourly     command    # once an hour: 0 * * * *

# examples
@reboot /home/user/startup.sh
@daily /home/user/backup.sh >> /var/log/backup.log 2>&1
@hourly /usr/local/bin/health-check.sh

# set MAILTO for email notifications
MAILTO="[email protected]"
@daily /home/user/report.sh

# disable email (discard output)
MAILTO=""
@daily /home/user/cleanup.sh > /dev/null 2>&1

# environment variables in crontab
PATH=/usr/local/bin:/usr/bin:/bin
SHELL=/bin/bash
HOME=/home/user
@daily /home/user/script.sh

# redirect output to log
@daily /home/user/script.sh >> /home/user/cron.log 2>&1

# log with timestamp
@daily echo "$(date): starting" >> /home/user/cron.log; /home/user/script.sh >> /home/user/cron.log 2>&1

# check cron service is running
systemctl status cron
systemctl status crond

anacron

anacron 专为不 always 开机的机器设计(笔记本电脑、台式机)。与 cron 不同,它在系统启动时运行错过的任务。只支持每日/每周/每月粒度。延迟字段添加随机等待以防止所有任务同时启动。systemd 计时器是现代替代——支持类似 cron 的调度,可以运行错过的任务(Persistent=true),并与 journalctl 集成日志。

linux
# anacron: run periodic jobs even if system was off
# /etc/anacrontab format:
# period  delay  job-id  command
#   1     5      daily   /home/user/daily.sh
#   7     10     weekly  /home/user/weekly.sh
#   30    15     monthly /home/user/monthly.sh

# view anacron config
cat /etc/anacrontab

# anacron directories (system-wide)
ls /etc/cron.daily/
ls /etc/cron.weekly/
ls /etc/cron.monthly/

# run anacron manually
sudo anacron -d            # run jobs in foreground with debug
sudo anacron -f            # force run all jobs
sudo anacron -u            # update timestamps only (don't run)

# run a specific job
sudo anacron -j daily      # run the 'daily' job

# check when jobs last ran
ls -l /var/spool/anacron/

# difference between cron and anacron:
# cron:
#   - requires system to be running at scheduled time
#   - minimum resolution: 1 minute
#   - per-user crontabs
#
# anacron:
#   - catches up missed jobs after downtime
#   - minimum resolution: 1 day
#   - system-wide only (runs as root)
#   - good for laptops/desktops that aren't always on

# systemd timers: modern alternative to cron
systemctl list-timers
sudo systemctl enable --now mytask.timer

at — 一次性定时任务

at 调度一次性命令(与 cron 的重复调度不同)。时间可以是绝对(10:30 AM、midnight)或相对(now + 30 minutes)。atq 列出待处理任务;atrm 移除。batch 在系统负载低于 0.8 时运行(可配置)。at 任务以用户环境运行。需要 atd 服务。用于提醒、延迟任务或在不保持登录的情况下调度关机。

linux
# schedule a command for later
echo "backup.sh" | at midnight
echo "shutdown -h now" | at 2am tomorrow

# interactive scheduling
at 2:30 PM
at> /home/user/report.sh
at> Ctrl+D                  # press Ctrl+D to submit

# schedule relative to now
at now + 30 minutes
at> echo "30 min passed" > /tmp/notice.txt
at> Ctrl+D

at now + 2 hours
at now + 1 day
at now + 1 week

# schedule for a specific time
at 10:30 AM
at 10:30 AM tomorrow
at 10:30 AM 2025-12-25
at 10:30 AM Dec 25

# list pending jobs
atq
at -l

# view a specific job
at -c 5                      # show job #5

# remove a job
atrm 5                       # remove job #5
at -d 5                      # alternative

# batch: run when load is low
batch
at> /home/user/heavy-computation.sh
at> Ctrl+D

# enable atd service
sudo systemctl enable --now atd

# check atd is running
systemctl status atd
16

归档与压缩

tar — 创建与提取

tar 将文件捆绑到单个归档中(默认不压缩)。标志是助记的:c=创建,x=提取,t=列出,f=文件,v=详细。-C 指定提取目录。--exclude 跳过模式。tar 保留文件权限、所有权和时间戳。从不可信来源提取前始终用 tar -tf 预览内容。-f 标志后必须跟文件名。

linux
# create a tar archive (no compression)
tar -cf archive.tar file1.txt file2.txt
tar -cf archive.tar directory/

# extract a tar archive
tar -xf archive.tar
tar -xf archive.tar -C /target/dir/    # extract to specific directory

# list contents without extracting
tar -tf archive.tar
tar -tvf archive.tar          # verbose (with details)

# verbose create/extract
tar -cvf archive.tar dir/     # show files being added
tar -xvf archive.tar          # show files being extracted

# append files to existing archive
tar -rf archive.tar newfile.txt

# extract specific files
tar -xf archive.tar path/to/file.txt
tar -xf archive.tar "file*.txt"

# exclude files
tar -cf archive.tar dir/ --exclude="*.log"
tar -cf archive.tar dir/ --exclude="node_modules"

# common flags:
# c = create
# x = extract
# t = list
# f = file (specify archive name)
# v = verbose
# r = append
# u = update (only newer files)
# C = change to directory

# preserve permissions (default for root)
tar -cpf archive.tar dir/     # p = preserve permissions

# show what would be done (dry run)
tar -tf archive.tar | head -10

tar 与压缩

tar 通过标志支持多种压缩算法:z(gzip),j(bzip2),J(xz),--zstd(zstd)。gzip 是标准(快速,到处都有);bzip2 压缩更好但更慢;xz 比率最好但最慢;zstd 是现代选择(最快,好比率)。现代 tar 在提取时自动检测压缩,所以 -xf 对任何格式都有效。压缩级别(1-9)以速度换大小。备份首选 xz 或 zstd。

linux
# tar + gzip (most common, .tar.gz or .tgz)
tar -czf archive.tar.gz dir/        # create
tar -xzf archive.tar.gz             # extract
tar -tzf archive.tar.gz             # list

# tar + bzip2 (better compression, slower)
tar -cjf archive.tar.bz2 dir/       # create
tar -xjf archive.tar.bz2            # extract
tar -tjf archive.tar.bz2            # list

# tar + xz (best compression, slowest)
tar -cJf archive.tar.xz dir/        # create
tar -xJf archive.tar.xz             # extract
tar -tJf archive.tar.xz             # list

# tar + zstd (fast + good ratio, modern)
tar --zstd -cf archive.tar.zst dir/ # create
tar --zstd -xf archive.tar.zst      # extract

# specify compression level (1-9, default 6)
GZIP=-9 tar -czf archive.tar.gz dir/    # max gzip compression
XZ_OPT=-9e tar -cJf archive.tar.xz dir/ # max xz compression

# compression comparison:
# gzip:  fast, medium compression (.tar.gz)
# bzip2: medium, good compression (.tar.bz2)
# xz:    slow, best compression (.tar.xz)
# zstd:  fastest, good compression (.tar.zst)

# extract: tar auto-detects compression
tar -xf archive.tar.gz    # works without -z flag
tar -xf archive.tar.xz    # works without -J flag

# compress to stdout (for piping)
tar -cz dir/ | ssh user@host "cat > backup.tar.gz"

zip 与 unzip

zip 在 Windows 上常见且广泛支持。-r 递归目录;-e 用密码加密(提示输入);-x 排除模式;-s 分割成多部分(大文件有用)。unzip -l 列出;-d 提取到目录;-t 测试完整性。与 tar+gzip 不同,zip 单独压缩每个文件,允许随机访问归档中的文件。跨平台共享时,zip 是最安全的选择。

linux
# create a zip archive
zip archive.zip file1.txt file2.txt

# zip a directory recursively
zip -r archive.zip directory/

# zip with password (encryption)
zip -e -r archive.zip directory/
zip -P password archive.zip file.txt   # password on command line (insecure)

# zip with specific compression level (0-9)
zip -9 -r archive.zip directory/       # maximum compression

# zip excluding files
zip -r archive.zip dir/ -x "*.log" -x "*/node_modules/*"

# split archive into parts
zip -s 100m archive.zip largefile.iso   # 100MB parts

# update/add files to existing zip
zip archive.zip newfile.txt

# list contents
unzip -l archive.zip
unzip -v archive.zip            # verbose with details

# extract
unzip archive.zip
unzip archive.zip -d /target/dir/

# extract specific files
unzip archive.zip file1.txt

# test archive integrity
unzip -t archive.zip

# extract to stdout
unzip -p archive.zip file.txt

# zipinfo: detailed listing
zipinfo archive.zip
zipinfo -1 archive.zip          # just filenames

gzip 与 gunzip

gzip 压缩单个文件(不是归档——多文件用 tar)。它用 .gz 文件替换原始文件;用 -k 保留。-c 输出到 stdout(用于管道)。zcat/zless 读取压缩文件而不解压。gzip 一次只处理一个文件,所以 tar + gzip 是目录的标准。压缩级别 9 给出最小文件但耗时更长;级别 1 最快。

linux
# compress a single file (replaces original)
gzip file.txt                # creates file.txt.gz, removes file.txt

# keep the original file
gzip -k file.txt             # keep original
gzip -c file.txt > file.txt.gz  # alternative (to stdout)

# set compression level (1-9, default 6)
gzip -1 file.txt             # fastest, least compression
gzip -9 file.txt             # slowest, best compression

# decompress
gunzip file.txt.gz           # creates file.txt, removes .gz
gzip -d file.txt.gz          # same as gunzip
gunzip -c file.txt.gz > file.txt  # keep original
gunzip -k file.txt.gz        # keep original (GNU)

# compress multiple files (each gets its own .gz)
gzip file1.txt file2.txt file3.txt

# recursive (compress all files in directory)
gzip -r directory/

# test integrity
gzip -t file.txt.gz

# list compression info
gzip -l file.txt.gz
# compressed  uncompressed  ratio  uncompressed_name
#       1234        5678    78.3%  file.txt

# zcat: view compressed file without extracting
zcat file.txt.gz
zcat file.txt.gz | grep "error"

# zless: pager for compressed files
zless file.txt.gz

# concatenate and decompress
cat file1.txt.gz file2.txt.gz | gunzip > combined.txt

# compress stdin
echo "data" | gzip > data.gz
tar -cf - dir/ | gzip > archive.tar.gz

xz 与 bzip2

bzip2 比 gzip 压缩更好但更慢。xz(LZMA)提供最佳压缩比率但最慢——非常适合归档。zstd 是现代选择:最快解压且比率好。lz4 极快但比率较低。分发软件首选 xz(最小下载)。实时压缩用 zstd 或 lz4。bzcat/xzcat/zcat 读取压缩文件而不解压——对日志分析有用。

linux
# bzip2: better compression than gzip
bzip2 file.txt               # compress (replaces original)
bzip2 -k file.txt            # keep original
bunzip2 file.txt.bz2         # decompress
bzip2 -d file.txt.bz2        # same as bunzip2

# bzip2 compression level (1-9, default 9)
bzip2 -9 file.txt

# bzcat: view bzip2-compressed file
bzcat file.txt.bz2 | grep "pattern"

# xz: best compression ratio
xz file.txt                  # compress (replaces original)
xz -k file.txt               # keep original
xz -d file.txt.xz            # decompress
unxz file.txt.xz             # same as xz -d

# xz compression level (0-9, default 6)
xz -9 file.txt               # maximum compression

# xz with extreme compression (very slow)
xz -9e file.txt

# xzcat: view xz-compressed file
xzcat file.txt.xz

# zstd: fast modern compressor
zstd file.txt                # compress
zstd -d file.txt.zst         # decompress
zstd -19 file.txt            # max compression
zstd -k file.txt             # keep original

# lz4: extremely fast
lz4 file.txt                 # compress
lz4 -d file.txt.lz4          # decompress

# compare compression ratios
ls -lh file.txt file.txt.gz file.txt.bz2 file.txt.xz

# benchmark compression
time gzip -9 file.txt
time xz -9 file.txt
17

SSH 与远程访问

SSH 连接

ssh 安全连接远程机器。-p 指定非默认端口;-i 选择私钥。ssh-copy-id 安装你的公钥实现免密登录(比密码安全得多)。-v 帮助诊断连接问题(密钥协商、认证步骤)。-X 启用 X11 转发用于远程 GUI 应用。频繁连接时,在 ~/.ssh/config 中配置别名。

linux
# basic connection
ssh user@hostname
ssh [email protected]
ssh [email protected]

# specify port (default 22)
ssh -p 2222 user@host

# use a specific private key
ssh -i ~/.ssh/id_ed25519 user@host

# run a single command and exit
ssh user@host "uname -a"
ssh user@host "ls -la /var/log"

# verbose (debug connection issues)
ssh -v user@host
ssh -vv user@host            # more verbose
ssh -vvv user@host           # most verbose

# forward X11 (GUI applications)
ssh -X user@host
ssh -Y user@host             # trusted X11 forwarding

# compression (slow connections)
ssh -C user@host

# keep alive
ssh -o ServerAliveInterval=60 user@host

# force SSH version
ssh -1 user@host             # SSH protocol 1 (insecure, avoid)
ssh -2 user@host             # SSH protocol 2 (default, secure)

# copy SSH key to remote (passwordless login)
ssh-copy-id user@host
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@host
ssh-copy-id -p 2222 user@host

# test connection without running commands
ssh -T user@host

SSH 密钥管理

推荐 Ed25519 密钥(比 RSA 更小、更快、更安全)。私钥必须 chmod 600 否则 SSH 拒绝使用。ssh-agent 在内存中缓存密码短语,每次会话只需输入一次;ssh-add -l 列出已加载的密钥。ssh-keygen -R 从 known_hosts 移除主机条目(服务器重装后有用)。始终通过带外验证主机指纹以防中间人攻击。绝不分享或提交私钥。

linux
# generate an SSH key pair (Ed25519, recommended)
ssh-keygen -t ed25519 -C "[email protected]"

# generate RSA key (4096 bits, if Ed25519 not supported)
ssh-keygen -t rsa -b 4096 -C "[email protected]"

# generate with custom filename
ssh-keygen -t ed25519 -f ~/.ssh/id_server -C "server key"

# generate without passphrase (automated scripts)
ssh-keygen -t ed25519 -N "" -f ~/.ssh/deploy_key

# copy public key to remote server
ssh-copy-id user@host

# view public key
cat ~/.ssh/id_ed25519.pub

# view fingerprint
ssh-keygen -l -f ~/.ssh/id_ed25519.pub

# key files:
# ~/.ssh/id_ed25519       private key (keep secret! chmod 600)
# ~/.ssh/id_ed25519.pub   public key (can share)

# authorized_keys on remote server
# add your public key to: ~/.ssh/authorized_keys
cat ~/.ssh/id_ed25519.pub | ssh user@host "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

# SSH agent (manages keys in memory)
eval "$(ssh-agent -s)"        # start agent
ssh-add ~/.ssh/id_ed25519     # add key to agent
ssh-add -l                   # list loaded keys
ssh-add -D                   # remove all keys from agent

# remove or change a key passphrase
ssh-keygen -p -f ~/.ssh/id_ed25519

# verify host key fingerprint (avoid MITM)
ssh-keygen -l -f /etc/ssh/ssh_host_ed25519_key.pub

# known_hosts management
ssh-keygen -R 192.168.1.100   # remove a host entry
ssh-keygen -F 192.168.1.100   # find a host entry

# key permissions (critical!)
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub

SCP — 安全复制

scp 使用 SSH 加密传输文件。-r 用于目录,-P(大写!)用于端口(ssh 用小写 -p)。大型或频繁传输优先用 rsync 而非 scp——rsync 恢复中断的传输且只发送差异。scp 在较新的 OpenSSH 版本中正被 sftp 替代,但仍广泛可用,适合快速复制。

linux
# copy local file to remote
scp file.txt user@host:/path/to/dest/
scp file.txt user@host:~/        # home directory

# copy remote file to local
scp user@host:/var/log/syslog ./
scp -r user@host:/var/log /tmp/  # recursive (directory)

# copy between two remote hosts
scp user1@host1:/file user2@host2:/dest

# specify port
scp -P 2222 file.txt user@host:/dest

# preserve attributes (timestamps, perms)
scp -p file.txt user@host:/dest

# compress during transfer
scp -C bigfile.tar user@host:/dest

# limit bandwidth (KB/s)
scp -l 1000 file user@host:/dest    # ~1 MB/s

SSH 配置文件

~/.ssh/config 让你为主机创建别名,避免带许多标志的长 ssh 命令。只需 'ssh dev' 即可使用所有正确设置连接。通配符(*.internal)应用于匹配的主机。此文件必须 chmod 600。IdentitiesOnly yes 防止 SSH 尝试 ~/.ssh 中的每个密钥(可能导致'认证失败过多')。这是 SSH 体验最大的改进。

linux
# ~/.ssh/config - simplify connections
Host dev
    HostName dev.example.com
    User alice
    Port 2222
    IdentityFile ~/.ssh/id_dev

Host prod
    HostName prod.example.com
    User deploy
    IdentityFile ~/.ssh/id_deploy
    ServerAliveInterval 60

# wildcard: all hosts in a domain
Host *.internal
    User admin
    ForwardAgent yes

# use: ssh dev  (instead of ssh -p 2222 [email protected])
#      scp file prod:/tmp/

# common useful options
Host *
    ServerAliveInterval 60      # keep connection alive
    ServerAliveCountMax 3       # disconnect after 3 missed
    AddKeysToAgent yes          # auto-add keys to agent
    IdentitiesOnly yes          # only use specified keys

端口转发与隧道

端口转发通过 SSH 加密通道传输流量。-L(本地)在你的机器上暴露远程服务;-R(远程)做反向(用于访问 NAT 后的机器);-D 创建 SOCKS 代理。-fN 在后台运行无 shell。ProxyJump (-J) 是跳转堡垒主机的现代方式——比嵌套 SSH 干净得多。这些对于安全访问内部服务至关重要。

linux
# local forward: access remote service locally
# local:8080 -> remote:80
ssh -L 8080:localhost:80 user@host
# then open http://localhost:8080 in browser

# local forward to a third host via jump server
ssh -L 8080:internal.db:3306 user@jumphost

# remote forward: expose local service to remote
# remote:8080 -> local:80
ssh -R 8080:localhost:80 user@host

# dynamic forward (SOCKS proxy)
ssh -D 1080 user@host
# then configure browser to use SOCKS5 proxy at localhost:1080

# run in background (no command, no terminal)
ssh -fN -L 8080:localhost:80 user@host

# jump host / proxy jump (OpenSSH 7.3+)
ssh -J user@jumphost [email protected]
# or in ~/.ssh/config:
#   Host internal
#       ProxyJump jumphost

# forward ports in config file
Host db
    HostName db.internal
    LocalForward 3306 localhost:3306
18

磁盘管理

列出块设备

lsblk 是列出磁盘和分区的现代方式(替代 fdisk -l 查看用途)。df 显示文件系统磁盘空间(-h 人类可读,-i 查看 inode——如果 inode 满了,即使有空间也无法创建文件)。du 测量目录大小;'sort -rh | head' 模式找出空间占用者。用 --max-depth 限制 du 的递归深度。

linux
# list block devices (modern, recommended)
lsblk                         # tree view
lsblk -f                      # with filesystem info
lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINT
lsblk -d                      # don't print partitions

# old way: list disks and partitions
sudo fdisk -l
sudo fdisk -l /dev/sda        # specific disk

# view partition table
sudo parted -l
sudo parted /dev/sda print

# filesystem disk space
df -h                         # human-readable
df -hT                        # with filesystem type
df -i                         # inode usage
df -h /                       # specific mount

# directory space usage
du -sh /path                  # summary
du -sh /*                     # top-level dirs
du -h --max-depth=1 /var      # one level deep
du -ah /var | sort -rh | head -10   # 10 largest

挂载与卸载

mount 挂载文件系统;umount 卸载。如果'目标忙',使用 -l(惰性)在不再使用时卸载。/etc/fstab 定义开机时挂载——编辑后始终在重启前用 'mount -a' 测试!UUID= 形式比 /dev/sdX 更可靠(重启后可能改变)。findmnt 比 mount 提供更清晰的视图。

linux
# mount a filesystem
sudo mount /dev/sdb1 /mnt/data
sudo mount -t ext4 /dev/sdb1 /mnt/data

# mount with options
sudo mount -o ro /dev/sdb1 /mnt/data          # read-only
sudo mount -o noexec /dev/sdb1 /mnt/data      # no executables
sudo mount -o uid=1000,gid=1000 /dev/sdb1 /mnt  # set owner

# mount an ISO image
sudo mount -o loop ubuntu.iso /mnt/iso

# unmount
sudo umount /mnt/data
sudo umount /dev/sdb1

# lazy unmount (busy filesystem)
sudo umount -l /mnt/data

# force unmount
sudo umount -f /mnt/data

# list mounted filesystems
mount | column -t
findmnt                        # cleaner tree view

# /etc/fstab - persistent mounts
# <device>  <mount>  <type>  <options>  <dump>  <pass>
# /dev/sdb1  /data    ext4   defaults   0       2

创建与格式化分区

2TB 以上磁盘使用 GPT(gpt 标签);MBR(msdos)是遗留默认。ext4 是安全的 Linux 默认;XFS 在 RHEL/CentOS 上常见;Btrfs 提供快照和压缩。mkfs 前始终仔细检查设备名——它会销毁所有数据!fsck 检查/修复文件系统(在卸载的文件系统上运行更安全)。parted 不交互且可脚本化,不像 fdisk。

linux
# interactive partition editor
sudo fdisk /dev/sdb
#   m = help, n = new, p = print, d = delete, w = write, q = quit

# GPT partitioning (for disks > 2TB)
sudo parted /dev/sdb mklabel gpt
sudo parted /dev/sdb mkpart primary ext4 0% 100%

# MBR partitioning
sudo parted /dev/sdb mklabel msdos
sudo parted /dev/sdb mkpart primary ext4 1MiB 100%

# format filesystem
sudo mkfs.ext4 /dev/sdb1           # ext4 (Linux default)
sudo mkfs.xfs /dev/sdb1            # XFS (RHEL default)
sudo mkfs.btrfs /dev/sdb1          # Btrfs
sudo mkfs.ntfs /dev/sdb1           # NTFS (Windows)
sudo mkfs.vfat /dev/sdb1           # FAT32

# label a filesystem
sudo e2label /dev/sdb1 mydata      # ext4
sudo xfs_admin -L mydata /dev/sdb1 # xfs

# check filesystem for errors
sudo fsck /dev/sdb1
sudo fsck -y /dev/sdb1             # auto-repair

逻辑卷管理 (LVM)

LVM 将物理磁盘抽象为灵活的逻辑卷。关键优势:可以调整卷大小并跨多个磁盘。层次结构是 PV(物理卷)-> VG(卷组,一个池)-> LV(逻辑卷,你格式化/挂载的)。ext4(resize2fs)和 XFS(xfs_growfs,仅增长)支持在线调整大小。快照实现一致性备份。LVM 在 RHEL/Fedora 上是标准。

linux
# LVM layers: PV -> VG -> LV
# physical volume (disk/partition)
sudo pvcreate /dev/sdb /dev/sdc
sudo pvdisplay
sudo pvs                        # summary

# volume group (pool of PVs)
sudo vgcreate myvg /dev/sdb /dev/sdc
sudo vgdisplay
sudo vgs

# logical volume (carved from VG)
sudo lvcreate -L 50G -n mylv myvg
sudo lvcreate -l 100%FREE -n mylv myvg   # use all space
sudo lvdisplay
sudo lvs

# use the LV (path: /dev/<vg>/<lv>)
sudo mkfs.ext4 /dev/myvg/mylv
sudo mount /dev/myvg/mylv /mnt/data

# resize LV (ext4)
sudo lvextend -L +10G /dev/myvg/mylv
sudo resize2fs /dev/myvg/mylv    # grow filesystem

# resize LV (xfs)
sudo lvextend -L +10G /dev/myvg/mylv
sudo xfs_growfs /mnt/data

# snapshot (point-in-time copy)
sudo lvcreate -L 5G -s -n mysnap /dev/myvg/mylv

Swap 与内存

Swap 使用磁盘空间扩展物理内存。Swap 文件(用 fallocate/mkswap 创建)比 swap 分区更简单,在 modern 内核上性能相同。swappiness(0-100)控制内核交换的激进程度——较低值保留更多在 RAM(对数据库好)。free -h 是快速内存摘要;/proc/meminfo 有详细分解。vmstat 1 显示持续的内存/cpu/io 统计。

linux
# show swap usage
swapon --show
free -h

# create a swap file (modern method)
sudo fallocate -l 4G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

# make permanent (add to /etc/fstab)
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

# remove swap file
sudo swapoff /swapfile
sudo rm /swapfile

# adjust swappiness (0-100, lower = less swap use)
cat /proc/sys/vm/swappiness       # default 60
sudo sysctl vm.swappiness=10      # runtime
# permanent: add to /etc/sysctl.conf

# memory info
free -h                           # summary
cat /proc/meminfo                 # detailed
vmstat 1                          # continuous
19

管道与重定向

标准流与重定向

每个进程有三个流:stdin(0)、stdout(1)、stderr(2)。> 重定向 stdout(>> 追加);2> 重定向 stderr。2>&1 将 stderr 合并到 stdout 的目标(顺序重要——放在最后)。&> 是 Bash 的 >file 2>&1 快捷方式。Here-doc(<<EOF)提供多行输入;引用分隔符('EOF')禁用变量扩展。/dev/null 是丢弃输出的黑洞。

linux
# three standard streams:
#   stdin  (0) - input
#   stdout (1) - normal output
#   stderr (2) - error output

# redirect stdout to file (overwrite)
echo "hello" > file.txt

# append stdout to file
echo "world" >> file.txt

# redirect stderr to file
ls /nonexistent 2> errors.log

# redirect both stdout and stderr
ls / /nonexistent > all.log 2>&1
ls / /nonexistent &> all.log        # bash shortcut

# discard output (send to /dev/null)
command > /dev/null 2>&1

# redirect stdin from file
sort < unsorted.txt
wc -l < file.txt

# here-string (feed string to stdin)
grep "error" <<< "some error text"

# here-document (multi-line input)
cat << EOF
Line one
Line two with $HOME expanded
EOF

# quoted here-doc (no expansion)
cat << 'EOF'
$HOME stays literal
EOF

管道与管道线

管道(|)将一个命令的 stdout 连接到另一个的 stdin,构建强大的管道。tee 将输出同时分流到文件和 stdout(记录日志同时查看很好用)。进程替换 <(cmd) 将命令的输出视为临时文件——对 diff 和 comm 等期望文件参数的命令至关重要。默认管道的退出状态是最后一个命令的;set -o pipefail 使任何阶段失败时管道失败。

linux
# pipe: connect stdout to stdin
command1 | command2

# count files
ls | wc -l

# find and kill
ps aux | grep nginx | grep -v grep

# filter and sort
cat access.log | grep "404" | sort | uniq -c | sort -rn | head

# chain transformations
cat data.csv | cut -d, -f2 | sort | uniq -c | sort -rn

# tee: write to file AND stdout
command | tee output.log
command | tee -a output.log        # append

# pipe stderr too
command 2>&1 | grep error

# pipefail: catch failures in pipeline
set -o pipefail                    # pipeline fails if any command fails

# process substitution (command as file)
diff <(ls dir1) <(ls dir2)
comm <(sort file1) <(sort file2)
while read line; do echo "$line"; done < <(grep pattern file)

xargs 与并行执行

xargs 将 stdin 转换为命令参数——将 find 输出管道到 rm、cp 或 grep 等命令的关键。始终用 -0 配合 find -print0 处理含空格/换行的文件名。-I {} 允许在命令中任意位置放置参数。-P N 并行运行 N 个命令。GNU parallel 是更强大的替代(进度条、远程执行、重试)。切勿未测试就运行 'xargs rm'——用 -t 预览或 -p 确认。

linux
# xargs: build arguments from stdin
echo "a b c" | xargs mkdir

# one argument per line
find . -name "*.bak" | xargs rm

# handle spaces in filenames (null-delimited)
find . -name "*.log" -print0 | xargs -0 rm

# limit arguments per command
find . -name "*.txt" | xargs -n 1 cp -t /dest/

# show commands before running
find . -name "*.bak" | xargs -t rm

# prompt before each command
find . -name "*.bak" | xargs -p rm

# replace string with argument
find . -name "*.jpg" | xargs -I {} convert {} {}.png

# parallel execution (GNU parallel is more powerful)
find . -name "*.png" | xargs -P 4 -I {} convert {} {}.jpg   # 4 parallel

# GNU parallel (if installed)
parallel -j 4 convert {} {.}.jpg ::: *.png
parallel gzip ::: *.log

命令替换与分组

$() 捕获命令输出(优先于反引号——嵌套干净,无需转义)。{ } 在当前 shell 中分组命令(注意空格和末尾的 ;);( ) 在子 shell 中运行(cd 等更改不影响父 shell)。&& 和 || 是短路运算符——'A && B || C' 模仿三元但 B 可能失败时有 bug。用于简洁的单行命令,但健壮脚本中优先用 if/else。

linux
# command substitution: use output as argument
files=$(ls *.txt)
today=$(date +%Y-%m-%d)
echo "Today is $today"

# backtick form (legacy, avoid)
files=`ls *.txt`

# arithmetic expansion
result=$(( 5 * 3 ))
count=$(( count + 1 ))

# group commands with { } (runs in current shell)
{ cd /tmp; ls; pwd; } > output.txt

# subshell with ( ) (runs in child process)
(cd /tmp && make clean && make)    # doesn't change your cwd

# sequential execution
cmd1 ; cmd2            # run cmd2 regardless of cmd1
cmd1 && cmd2           # run cmd2 only if cmd1 succeeds
cmd1 || cmd2           # run cmd2 only if cmd1 fails

# background
cmd &                  # run in background
cmd1 & cmd2 &          # both in parallel

# conditional pipeline
grep -q "error" log.txt && echo "found" || echo "not found"

实用管道模式

这些模式将管道、重定向和文本工具组合成强大的单行命令。'sort | uniq -c | sort -rn | head' 模式是通用的频率分析器。awk + sort + uniq 是标准的日志分析工具包。进程替换 <(sort ...) 为 join/comm 提供排序输入。始终引用 tr 模式中的特殊字符。这些管道体现了 Unix 哲学:小工具组合解决复杂问题。

linux
# top 10 largest files
du -ah . | sort -rh | head -10

# find most frequent log entries
cat access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head

# extract and count HTTP status codes
awk '{print $9}' access.log | sort | uniq -c | sort -rn

# find files modified in last 24h, grouped by size
find . -mtime -1 -type f -exec du -h {} + | sort -rh

# unique IPs that hit /admin
grep "/admin" access.log | awk '{print $1}' | sort -u

# word frequency in a text file
tr -s ' ' '\n' < file.txt | sort | uniq -c | sort -rn | head

# join CSV files on first field
join -t, <(sort -t, -k1 file1.csv) <(sort -t, -k1 file2.csv)

# parallel downloads
cat urls.txt | xargs -n 1 -P 4 wget -q

# find which process uses the most memory
ps aux | sort -nk 4 | tail -5

# count lines matching pattern across files
grep -c "ERROR" *.log | awk -F: '{sum+=$2} END {print sum}'

这篇内容对您有帮助吗?

学习路径

从零开始学习

通过结构化课程从头学习这个语言。