为什么sh对这些命令的解释与zsh不同?
上下文:我正在尝试获取我的 Linux 机器上安装的字体名称。名称在两个冒号之间。当我使用 zsh 运行此脚本时,它可以工作。当我切换到 sh 时,它会中断。它可能会删除 n 个字符,因为输出都是一行。
cmd="$(fc-list)"
names="$(echo $cmd | grep -oP "(?<=: ).*?(?=:)")"
echo $names
哪个命令会导致问题?它不符合 POSIX 标准吗?
回答
为什么 sh 对这些命令的解释与 zsh 不同?
因为它们是不同的shell所以规则也不同。
哪个命令会导致问题?
echo $cmd
和
echo $names
它不符合 POSIX 标准吗?
该代码本身是有效的 POSIX 代码。不进行分词的 zsh shell 的行为不符合 POSIX。
在 POSIX shell 中,不带引号的扩展会进行分词。因为默认的 IFS 是空格制表符和换行符,所以这些字符在根据扩展结果创建单词时会被删除,并作为单独的单词传递echo给在一行上输出它们。要禁用分词(和文件名扩展),您需要引用扩展。也喜欢printf到echo。
cmd="$(fc-list)"
names="$(printf "%sn" "$cmd" | grep -oP "(?<=: ).*?(?=:)")"
printf "%sn" "$names"