Patrik
Patrik

Reputation: 107

Why does sh interpret these commands differently to zsh?

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?

Upvotes: 0

Views: 193

Answers (1)

KamilCuk
KamilCuk

Reputation: 141155

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"

Upvotes: 5

Related Questions