Why does sh interpret these commands differently to zsh?

狂风中的少年 提交于 2020-12-07 16:42:04

问题


Context: I am trying to get the names of fonts installed on my Linux machine. The name is between two colons. When I run this script using zsh, it works. When I switch to sh it breaks. It probably deletes \n characters, because the output is all one line.

cmd="$(fc-list)"
names="$(echo $cmd | grep -oP "(?<=: ).*?(?=:)")"
echo $names

Which command causes the issues? Is it not POSIX compliant?


回答1:


Why does sh interpret these commands differently to zsh?

Because they are different shell the rules are different.

Which command causes the issues?

echo $cmd

and

echo $names

Is it not POSIX compliant?

The code, by itself, is valid POSIX code. The behavior of zsh shell that doesn't do word splitting is not compliant with POSIX.

In POSIX shell unquoted expansions undergo word splitting. Because default IFS is space tab and newline, these characters are erased when creating words from the result of expansion and passed as separate words to echo which outputs them on one line. To disable word splitting (and filename expansion), you need to quote the expansion. Also prefer printf to echo.

cmd="$(fc-list)"
names="$(printf "%s\n" "$cmd" | grep -oP "(?<=: ).*?(?=:)")" 
printf "%s\n" "$names"


来源:https://stackoverflow.com/questions/65155548/why-does-sh-interpret-these-commands-differently-to-zsh

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!