Bash:想确认参数有没有被拆开,可以临时用 `printf '<%s>\n'` 看一眼

33 次浏览3 条回复

写 shell 时最容易迷糊的地方之一,就是变量到底是一个参数,还是被空格拆成了好几个。临时用 printf '<%s>\n' 打印一下,每个参数一行,会比直接 echo 清楚不少。

环境:bash 4+。可以直接试:

name='hello world'

printf '<%s>\n' $name
printf '<%s>\n' "$name"

第一段没加引号,大概会看到:

<hello>
<world>

第二段加了引号,就是一个完整参数:

<hello world>

这个小写法很适合排查脚本里路径带空格、参数拼接不对的问题。不是啥高级技巧,但能少猜很多。

这个看数组也挺方便,比如:

args=("hello world" "*.md")
printf '<%s>\n' "${args[@]}"

一行一个参数,连通配符有没有被提前展开也能看出来。排查脚本入参时比盯着 set -x 猜舒服一点。

还有个小习惯:如果是在函数里转发参数,尽量用 "$@",别用 $* 或没加引号的 $@

f() {
  printf '<%s>\n' "$@"
}

f "hello world" "a*b"

这样每个原始参数还是一个参数,配合你这个打印法看得很直观。

顺手再补一个 Bash 自带的 %q,有时候看隐藏空格、换行会更明显:

x=$'a b\ncd'
printf '<%s>\n' "$x"
printf '<%q>\n' "$x"

第二行会把值按 shell 可读的形式转义出来。平时还是 %s 看参数个数,怀疑里面混了奇怪字符时再用 %q 挺搭。