POSIX habits
POSIX 习惯
“POSIX 习惯”通常指在编写 Unix/Linux 命令行程序、Shell 脚本或 C 程序时,遵循 POSIX(可移植操作系统接口)标准所形成的常见做法和约定。它既包含语法/接口层面的规范,也包含行为和风格上的惯例。
下面从几个常见角度来说明。
1. 命令行选项的习惯
POSIX 对实用程序的命令行参数有明确约定,最典型的是:
- 短选项用单个
-,如-a、-l。 - 短选项可以合并:
ls -la等价于ls -l -a。 - 选项和选项参数可以分开或连写:
grep -e patterngrep -epattern(部分实现支持)
--表示选项结束:用来删除名为1
rm -- -file
-file的文件。- 长选项通常用
--,如--help、--version,但这更多是 GNU 习惯,不是严格 POSIX。
POSIX 还规定了一些标准选项含义,例如:
-f:force / file-i:interactive-r:recursive(但并非所有命令都这样)-v:verbose-n:no-op / dry-run / numeric
2. 退出状态码的习惯
POSIX 程序通常遵循:
- 0 表示成功
- 非 0 表示失败
- 1 通常表示一般错误
- 2 常用于用法错误(如参数错误)
- >128 通常表示被信号终止(如 130 = 128 + SIGINT)
Shell 中常见写法:
1 | if command; then |
3. 标准输入/输出/错误
POSIX 习惯:
- 正常输出到 stdout
- 错误和诊断信息到 stderr
- 程序应尽量支持管道和重定向
例如:
1 | command > out.txt 2> err.txt |
C 程序中:
1 | fprintf(stdout, \"normal\\n\"); |
4. Shell 脚本中的 POSIX 习惯
如果写 #!/bin/sh 脚本,通常要遵循 POSIX sh,而不是 bash 扩展。
常见 POSIX 习惯:
- 使用
$(...)而不是反引号(反引号也可移植,但$()更清晰) - 变量引用加引号:
1
echo \"$var\"
- 使用
[ ]而不是[[ ]] - 不使用数组、
local、function等 bash 扩展 - 使用
command -v检查命令是否存在:1
2
3if command -v git >/dev/null 2>&1; then
...
fi - 使用
set -e要谨慎,因为它在某些 POSIX 场景下行为微妙
一个典型的 POSIX 风格脚本:
1 |
|
5. 文件与路径习惯
- 路径分隔符是
/ - 隐藏文件以
.开头 - 临时文件常放在
/tmp,并使用mktemp - 配置常放在
/etc - 用户配置常以
~/.xxx或~/.config/xxx形式存在
6. 文本流与行习惯
POSIX 工具通常按行处理文本:
- 每行以
\\n结尾 - 工具如
grep、sed、awk、sort、cut都面向行 - 没有输出时通常不报错,只是无输出
例如:
1 | grep pattern file |
找到就输出,没找到退出码为 1。
7. C 程序中的 POSIX 习惯
- 使用
open/read/write/close而不是只依赖 C 标准库 - 检查系统调用返回值
- 处理
EINTR - 使用
fork/exec而不是system - 信号处理使用
sigaction而不是signal - 头文件如
<unistd.h>、<fcntl.h>、<sys/stat.h>
例如:
1 |
|
8. “POSIX 习惯”常见的反面例子
- 在
#!/bin/sh里用[[ ]]、数组、function、local - 把错误信息输出到 stdout
- 成功时返回非 0,失败时返回 0
- 不引用变量导致空格分词问题
- 依赖 GNU 特有选项却声称可移植
- 用
echo -e(POSIXecho对-e的支持不一致)
总结
“POSIX 习惯”可以概括为:
- 接口可移植:使用 POSIX 标准定义的命令、选项、系统调用。
- 行为可预测:退出码、stdout/stderr、选项解析遵循约定。
- Shell 脚本克制:写
sh就只用 POSIX sh 特性。 - 面向文本流:按行处理,支持管道和重定向。
- 错误处理明确:失败给非 0,诊断信息进 stderr。
如果你是在某个具体场景里看到“POSIX 习惯”这个词,比如写脚本、写 C 程序、还是命令行工具设计,可以告诉我,我可以针对那个场景展开。