bash --version / echo $BASH_VERSION 查看版本help / help cd 查看内建帮助;man bash 手册set -o emacs 或 set -o vi 切换行编辑模式(Readline)shopt -s extglob 启用扩展通配;shopt -s globstar 启用 **set -euo pipefail 更健壮脚本:遇错退出/未定义变量报错/管道传递失败Ctrl+A 行首;Ctrl+E 行尾;Alt+F/B 词前进/后退;Ctrl+F/B 字符Ctrl+U 删至行首;Ctrl+K 删至行尾;Alt+D 删到词尾;Ctrl+W 删到词首Ctrl+Y 粘贴(yank);Alt+Y 轮换 kill-ring;Ctrl+_ 撤销Ctrl+R 反向搜索;↑/↓ 上/下一条;Alt+. 上条命令最后一个参数Ctrl+L 清屏;Ctrl+C 中断;Ctrl+D EOF(空行时退出)set -o vi 后提供 vi 风格按键。name=value 赋值(等号左右无空格);readonly name 只读declare -i n=0 整型;declare -a arr 索引数组;declare -A map 关联数组local x 函数内局部变量;export x 传递到子进程环境$0 $1..$9 ${10} 位置参;$# 个数;$@/$* 全部;$$ PID;$! 后台 PID;$? 上一退出码;$- 选项"$@" 逐参保留分隔;"$*" 合并为单字符串(由 IFS 连接)。${v:-word} 默认;${v:=word} 置默认;${v:?msg} 未设报错;${v:+alt} 已设用 alt${#v} 长度;${v:offset[:len]} 子串;数组:${arr[@]:o:l} 切片${v#pat}/${v##pat} 去前缀(最短/最长);${v%pat}/${v%%pat} 去后缀${v/pat/repl} 首次;${v//pat/repl} 全部;${v/#pat/repl} 首部;${v/%pat/repl} 尾部${v^}/${v^^} 首字母/全部大写;${v,}/${v,,} 小写${!name} 以变量值作为变量名再取值;关联数组键:${!map[@]}{1..5}、{a..e}、{x,y,z}(在引号外生效,发生于路径名展开之前)$(( expr ));自增:((i++));比较:((a < b)) 返回状态$(cmd)(推荐)/ `cmd`(旧);进程替换:<(cmd) / >(cmd)$'\n' C 风格转义;ANSI-C 引用x=${x##*( )} 去前空格;x=${x%%*( )} 去后空格(需 shopt -s extglob)$/$( ) 展开;$'..' 允许转义[ ]:字符串:=/!=;整数:-eq -ne -lt -le -gt -ge;文件:-f -d -e -s -r -w -x[[ ]]:支持模式匹配 == pat;正则 =~;短路与 &&/||[[ ]] 内不进行路径名扩展与单词分割,推荐在 Bash 使用。if [[ $s =~ ^([0-9]+)-([a-z]+)$ ]]; then echo ${BASH_REMATCH[1]} ${BASH_REMATCH[2]}; fifor x in a b; do ...; done;C 风格:for((i=0;i<n;i++)); do ...; donewhile read -r line; do ...; done < file 安全读取行case $x in pat) ...;; *) ...;; esac 模式分支;可配 shopt -s nocasematch 忽略大小写break/continue;带层级:break 2read -r line 禁止反斜杠转义;read -a arr 读入数组read -n 1 -s key 无回显读取 1 字符;read -t 5 var 超时mapfile -t arr < file 按行读入数组;mapfile -t -n 10 arr < file 只读 10 行printf 'x=%q\n' "$x" 安全转义输出;printf -v out '%04d' 7 直接赋值变量%s 字符串;%q 可重用转义;%d 整数;%f 浮点;\n 换行while getopts ":ab:c" opt; do
case $opt in
a) flag_a=1 ;;
b) arg_b=$OPTARG ;;
c) flag_c=1 ;;
:) echo "缺少参数: -$OPTARG"; exit 2 ;;
\?) echo "未知选项: -$OPTARG"; exit 2 ;;
esac
done
shift $((OPTIND-1))
: 前缀开启“缺参”错误处理;带冒号的选项声明为“需要参数”name() { local x; ...; } 或 function name { ...; }return N(0 成功);输出用 echo/printf 传递$1…;全部:"$@";个数:$#arr=(a b c);arr[2]=X;取值:${arr[0]}/${arr[@]}${#arr[@]};下标:${!arr[@]};切片:${arr[@]:1:2}declare -A map; map[foo]=bar;键:${!map[@]};值:${map[@]}>/>> 输出;< 输入;n>file 指定 fdcat <<EOF ... EOF(引用定界符可关闭展开);Here 字符串:cmd <<< "$str"2>&1;Bash 专有:&>file(stdout+stderr 到文件)diff <(cmd1) <(cmd2);需要 bash 或兼容实现set -o pipefailexec 3<> file 打开 fd3 读写;echo hi >&3 写入;read -u 3 x 从 fd3 读取exec 3>&- 关闭 fd3;cmd >&- 关闭 stdout;cmd 2>&- 关闭 stderrcmd & 后台;jobs 查看;fg %1/bg %1 前/后台;disown %1 脱离Ctrl+Z 挂起;kill -SIGCONT %1 继续coproc name { ...; } 协程进程(创建管道 FD)set -m 开启作业控制。history / history -c 清空;!n 第 n 条;!! 上一条;!$ 上条最后参数alias ll='ls -alh' 定义;unalias ll 取消;type -a cmd 查看解析顺序HISTCONTROL=ignoredups:erasedups;HISTSIZE/HISTFILESIZE 控制历史大小shopt -s histverify 执行前可编辑 !... 展开结果;fc -e - 打开编辑历史bash -n script.sh 语法检查;bash -x script.sh 跟踪执行set -x/set +x 运行时开启/关闭跟踪;PS4='+$LINENO: ' 行号提示trap 'cleanup' EXIT 退出清理;trap 'handler' ERR 错误陷阱trap 'echo SIGINT' INT;trap -p 查看;trap - INT TERM 清除set -e 遇错即退:谨防与条件判断/管道组合引发的误退,可配合 || true 等模式shopt -s extglob:@(p1|p2) 其一;?(p) 0/1 次;*(p) 任意次;+(p) ≥1 次;!(p) 非shopt -s globstar:** 递归匹配目录(如 **/*.sh)_foo() { COMPREPLY=( $(compgen -W "start stop restart" -- "${COMP_WORDS[COMP_CWORD]}") ); }complete -F _foo foo 为命令 foo 安装补全;complete -r foo 移除command ls 跳过别名/函数调用外部;builtin echo 强制内建;enable -n echo 禁用内建hash -r 清空命中缓存;type -a 显示解析路径( list ) 在子 shell 执行(变量修改不回传);{ list; } 在当前 shell(末尾必须分号或换行)source file/. file 在当前 shell 读取执行(共享作用域)nullglob 空模式展开为零参数;dotglob 匹配点文件;nocaseglob 忽略大小写failglob 无匹配时报错;lastpipe 管道最后一个在当前 shell 运行(非交互)checkwinsize 命令后自动更新 LINES/COLUMNS;cdspell/dirspell 轻微拼写修复cmdhist/lithist 合并多行命令到历史、保留换行;expand_aliases 在非交互中启用别名fish --version;help 打开文档;man fish;fish_config Web 配置and/or/not(无 &&/||/!)set name value;作用域:set -l 局部、-g 全局、-U 通用、-x 导出1 开始:$var[1];长度:count $var$argv;追加:set var $var new;删除:set -e varset files (ls *.md)(圆括号);子串:string sub -s 2 -l 3 $sstring split , $s;string join , $list;修剪:string trimstring match -r '^[0-9]+';string replace -r '(foo)' 'bar'math '1+2*3'(无 $(( )))if test -f file; ...; else if test -d dir; ...; else; ...; endfor x in $list; ...; end;while CONDITION; ...; endswitch $x; case pat; ...; case '*'; ...; endfunction hello; echo hi $argv; end;列出:functionscomplete -c foo -a "(seq 1 5)" -d 'numbers';查看:complete -C fooabbr -a gs 'git status';列出:abbr -scmd > out;cmd >> out;cmd 2> err;(部分版本支持 ^ 表示 stderr)cmd | other;cmd |& other(合并输出)echo $pipestatus(列表,存放各段退出码)set -x PATH /opt/bin $PATH(无需冒号拼接)~/.config/fish/config.fish;通用变量:set -U var valstatus、type、contains、path、count、time、read、argparse$(cmd);Fish (cmd)&&/||/!;Fish and/or/not[[ ]]/[ ];Fish 使用 if/test(无 [[ ]])$(( ));Fish math$argv 为全部参数local/export;Fish set -l/-g/-U/-xalias;Fish 推荐 abbr 与函数set -x PATH /path $PATH!!/!$ 历史展开;Fish 用自动建议与 historycomplete/compgen;Fish complete(语法不同)set -o pipefail;Fish $pipestatus2>/&>;Fish 常用 2>(部分版本支持 ^)do ... done;Fish end[[ =~ ]];Fish string match/replace -r~/.bashrc;Fish ~/.config/fish/config.fishsource.html 为原始素材(已据此迁移与审校)refmap.md 列出章节映射与修改说明