Basic Linux CLI
命令的基本组成
命令 子命令 [选项] [参数] [重定向] [控制符或管道]
Command Subcommand [Options] [Arguments] [Redirection] [Control Characters or Pipes]- 这里面除了命令是必须的, 其它的都是可选的 (就像 Python 的函数参数一样, 不写的话会有默认值!).
重要例子
git submodule update --initsubmodule和update是子命令--init是选项, 参数默认是更新所有模块. (也可以加参数:git submodule update --init --recursive third_party/python/pythondata_cpu_serv.)
# 如果系统中找不到 wget 命令,就把 wget 加入 missing 数组
missing=()
if ! which wget >/dev/null; then
missing+=(wget)
fi>: 重定向, 表示把标准输出 (即命令正常的输出) 写到某个地方./dev/null: 黑洞设备, 任何写入它的数据都会被系统丢弃.- 如果
which wget >/dev/null没成功, 则执行then后面的语句 (即只关心是否存在wget命令, 不关心它的输出).
grep "apt" ./scripts/setup- 在
./scripts/setup文件中查找包含"apt"字符串.
in_ci=0
if [ $# -gt 0 ] ; then
if [ $1 == "-ci" ] ; then
in_ci=1
fi
fi$#: 表示传递给脚本的参数个数.gt: 表示大于 (greater than).$1: 表示第一个参数.
cat file.txt # 打印文件内容
cat a.txt b.txt > merged.txt # 合并多个文件内容到一个新文件mkdir -p /path/to/directory # 创建目录, 如果上级目录不存在则创建# 假设 env.sh 有这个内容: MY_VAR="hello"
bash env.sh
echo "$MY_VAR" # 空的
source env.sh # 会在当前 shell 里保留变量
echo "$MY_VAR" # 输出 hello常见选项
-C: Change, 切换到指定目录.-h或--help: 显示帮助信息-v或--version: 显示版本信息-l或--long: 显示详细信息-a或--all: 显示所有内容,包括隐藏文件-r或--recursive: 递归操作-d或--directory: 仅显示目录 / 是否存在目录-f:--force, 强制执行操作- filename, 文件名
set -e: 如果有错误就退出 (exit) 脚本-p或--parents: 创建目录时如果不存在则会创建.
I/O 模型
输出/输出/错误
每个命令启动时, 系统会为它创建 3 个文件描述符 (file descriptor, FD):
FD 0 → 标准输入 (stdin) 默认为键盘
FD 1 → 标准输出 (stdout) 默认为终端
FD 2 → 标准错误 (stderr) 默认为终端重定向 (Redirection)
1>: 重定向 FD1, 将指令成功执行的结果输出到指定文件 (覆盖原文件).- 可以省略
1, 直接用>. - 错误信息不会被写进文件, 仍然显示在终端.
echo hello > out1.txtout1.txt
hello- 可以省略
2>: 重定向 FD2, 将指令执行时的错误信息输出到指定文件 (覆盖原文件).ls nonexistent_file 2> err1.txterr1.txt
ls: cannot access 'nonexistent_file': No such file or directoryFD1, FD2 分开存:
ls nonexistent_file > out2.txt 2> err2.txtout2.txt
err2.txt
ls: cannot access 'nonexistent_file': No such file or directoryFD2 当作 FD1 存:
ls nonexistent_file > all.txt 2>&1all.txt
ls: cannot access 'nonexistent_file': No such file or directory
>>: 追加 FD1echo hello >> out3.txt echo world >> out3.txtout3.txt
hello world
管道 (Pipes)
Shell 预处理
正则表达式 (Regular Expressions, regex)
*: 匹配零个或多个字符?: 匹配单个字符[abc]: 匹配方括号内的任意一个字符 (a, b, 或 c)[a-z]: 匹配指定范围内的任意一个字符 (小写字母 a 到 z)[^abc]: 匹配不在方括号内的任意一个字符 (不是 a, b, 或 c)^: 匹配行的开头$: 匹配行的结尾\: 转义字符, 用于匹配特殊字符本身 (如\*,\?,\\)
重定向
不改变命令本身, 而是改变命令默认的输入输出方式.
Shell 脚本
TODO
其它
Command Substitution 命令替换
echo "Today is $(date)"date本身就是命令! 执行的时候将它输出的结果作为字符串替换掉 (placeholder 的感觉).- 还有一些经常用在命令替换的命令:
# dirname 纯纯基于字符串 (不管路径是否存在)
dirname /home/user/file.txt → /home/user
dirname /home/user/ → /home
dirname foo/bar → foo
dirname foo → .
dirname this/path/not/exist → this/path/notpwd # 当前工作目录
realpath # 显示当前绝对路径常用命令
df -h # 查看磁盘使用情况
poweroff # 关机
ls -a # 列出当前目录下的所有文件和目录 (包括隐藏文件)apt和apt-get: 前者面向日常用户, 更简洁; 后者是更底层的传统工具, 适合脚本和精确控制.查看 manual:
# -A 3: 显示匹配行之后的 3 行 # -B 1: 显示匹配行之前的 1 行 man cc | grep -A 3 -B 1 " -g "
Vim Cheatsheet
