必须加引号:空格和特殊字符的硬性防线;变量含空格、制表符、*、?、|、>等时,不加引号会导致解析错误、截断或安全风险。

在 Linux Shell 中拼接变量时,特殊字符(如空格、$、*、&、>、换行符等)容易被 Shell 误解析,导致命令报错、截断、展开异常甚至安全风险。关键不是“避开”它们,而是用引号和语法规范明确告诉 Shell:哪些是字面量,哪些要展开。
必须加引号:空格和特殊字符的硬性防线
只要变量值可能含空格、制表符、星号、问号、管道符、重定向符号(>
-
错误写法:
file=$HOME/my file.txt→ Shell 把my和file.txt当成两个独立参数,报file.txt: command not found -
正确写法:
file="$HOME/my file.txt"或file="$HOME"/"my file.txt" - 路径、用户输入、日志内容、配置项几乎都建议默认加双引号,除非你100%确认只含字母数字下划线且无空格
推荐用 ${VAR}:消除变量名边界的歧义
当变量后紧跟其他字符(尤其是字母、数字、下划线)时,Shell 无法判断变量名在哪结束。比如 $user123 会被当作一个变量名,而非 $user 加上字符串 123。
-
不安全拼接:
echo "User:$user123"→ 查找变量user123,若不存在则输出User: -
安全拼接:
echo "User:${user}123"→ 明确界定变量是user,后面123是纯文本 - 即使没有歧义(如
$user后跟空格或标点),也统一用${user}提高可读性和一致性
拼接含命令替换或变量嵌套时,优先用双引号+${}
需要在拼接中插入命令结果(如 $(date))或组合多个变量时,双引号能同时支持变量替换和命令替换,而单引号会完全禁用它们。
-
有效拼接:
msg="Log at $(date): ${host}_status" -
无效拼接:
msg='Log at $(date): ${host}_status'→ 输出原样字符串,不执行命令也不展开变量 - 避免混用引号嵌套混乱:不要写
"text '$var'",改用"text ${var}"更清晰
对不可信输入,额外做转义或过滤(进阶防护)
如果变量来自用户输入、文件读取或网络响应,仅靠引号还不够。例如用于正则匹配、SQL 拼接或 eval 场景时,需进一步处理:
- 用于
awk正则模式,优先用-v传参:awk -v pat="$input" '$0 ~ pat',而非awk "/$input/" - 用于
sed替换,若$input含斜杠,可换分隔符或预处理:sed "s|old|$input|g" - 绝对避免
eval "echo $unsafe_var"—— 这会执行任意代码











