![¿Por qué echo “$USER:staff” arroja zsh: mala sustitución?](https://rvso.com/image/1646030/%C2%BFPor%20qu%C3%A9%20echo%20%E2%80%9C%24USER%3Astaff%E2%80%9D%20arroja%20zsh%3A%20mala%20sustituci%C3%B3n%3F.png)
Desconcertado porque echo "PATH=$PATH:/usr/local/sbin"
no lo hace (pensé que tenía algo que ver con :
).
Además, en Bash, ambos comandos funcionan como esperaba.
$ echo "PATH=$PATH"
PATH=/usr/local/bin
$ echo "PATH=$PATH:/usr/local/sbin"
PATH=/usr/local/bin:/usr/local/sbin
$ echo "$USER:staff"
zsh: bad substitution
Respuesta1
Porque el :s
después $USER
se interpreta como unmodificador de expansión. Puedes ver esto claramente si haces lo siguiente:
% autoload -Uz compinit; compinit # Init completion system
% zstyle ':completion:*' group-name '' # Enable completion grouping
% zstyle ':completion:*' format '%d' # Add titles to the groups
% print $USER: # and press Tab or ^D right after the `:`
modifier
& -- repeat substitution
A -- as ':a', then resolve symlinks
P -- realpath, resolve '..' physically
Q -- strip quotes
a -- absolute path, resolve '..' lexically
c -- PATH search for command
e -- leave only extension
g -- globally apply s or &
h -- head - strip trailing path element
l -- lower case all words
q -- quote to escape further substitutions
r -- root - strip suffix
s -- substitute string
t -- tail - strip directories
u -- upper case all words
Y como puede ver en la lista anterior, :/
no es un modificador de expansión.
¿Se recomienda usar siempre
${PATH}
,${USER}
, etc... entonces?
No, generalmente está bien usar solo $USER
, peroa veces,Como puede ver, es necesario utilizar ${USER}
. :)
Sin embargo, con respecto al código de tu pregunta, puedo darte otras dos recomendaciones para usar en Zsh:
- Usar
$path
en lugar de$PATH
y - usar
print
en lugar deecho
.
% print $PATH
/usr/local/bin
% print $path
/usr/local/bin
% path+=/usr/local/sbin # $path is an array, not a string
% print $PATH # $path and $PATH are "tied" & automatically in sync
/usr/local/bin:/usr/local/sbin
% print -c $path # Print the items in columns, like `ls`
/usr/local/bin /usr/local/sbin
% print -l $path # Print one item per line, like `ls -l`
/usr/local/bin
/usr/local/sbin
% path+=/usr/local/sbin
% print -c $path
/usr/local/bin /usr/local/sbin /usr/local/sbin
% typeset -U PATH path # Make each item unique/Eliminate duplicates
% print -c $path
/usr/local/bin /usr/local/sbin