cd ~ <usuário> é possível, mas por que não podemos cd ~ "$ USER" ou cd ~ $ {USER}

8

Estou curioso por que não podemos mudar para o diretor de casa de um usuário com

$ cd ~"$USER"

ou

$ cd ~${USER}
Neo_Returns
fonte
4
Porque é muito mais simples digitar "cd"?
jamesqf
7
@ jamesqf, todos sabemos o que pode ser feito ... a questão aqui é sobre o que não pode ser feito e por quê?
Neo_Returns 17/05/19

Respostas:

20

Isso depende muito da concha e da ordem em que as expansões são feitas nessas conchas.

~$userexpande para o diretório inicial do usuário cujo nome está armazenado em $usercsh (de onde esse ~userrecurso vem), AT&T ksh, zsh, fish.

Observe, no entanto, estas variações:

$ u=daemon/xxx csh -c 'echo ~$u'
/usr/sbin/xxx  # same in zsh/fish
$ u=daemon/xxx ksh93 -c 'echo ~$u'
~daemon/xxx

$ u=daemon/xxx csh -c 'echo ~"$u"'
Unknown user: daemon/xxx.
$ u=daemon/xxx zsh -c 'echo ~"$u"'
/usr/sbin/x  # same in fish

$ u=" daemon" csh -c 'echo ~$u'
/home/stephane daemon
$ u=" daemon" zsh -c 'echo ~$u'
~ daemon  # same in ksh/fish

$ u="/daemon"  csh -c 'echo ~$u'
/home/stephane/daemon  # same in zsh
$ u="/daemon"  fish -c 'echo ~$u'
~/daemon  # same in ksh

Ele se expande para o diretório inicial do usuário nomeado literalmente $userem bash(desde que o usuário exista, o que é muito improvável, é claro).

E nem em pdksh, dash, yash, presumivelmente porque eles não consideram $userser um nome de usuário válido.

Stéphane Chazelas
fonte
Você pode me sugerir onde posso aprender mais sobre a expansão em várias conchas.
Neo_Returns
6
@Neo_Returns, seus respectivos manuais e, quando isso não é claramente documentada, com tentativa e erro e o código-fonte para aqueles onde ele está disponível ...
Stéphane Chazelas
10

A expansão do til é uma etapa separada no processamento da linha de comando. Isso acontece pouco antes da expansão variável.

Se o til for seguido por algo que não seja uma barra, ele será expandido para o diretório inicial do usuário cujo nome está seguindo o til, como em, por exemplo ~otheruser. Como $USERnão é expandido nesse ponto e como é improvável que corresponda a um nome de usuário válido, o til fica inalterado.

$USERprovavelmente será o nome de usuário do usuário atual; portanto, sua expressão provavelmente poderá ser substituída por apenas ~.

Kusalananda
fonte
6

Como outras respostas apontaram, o comportamento depende de qual ordem o shell faz ~e as $expansões e se ele fará os dois pela mesma palavra.

O comportamento que você estava procurando é possível obter bashcom uma mudança muito pequena no seu comando. Basta prefixar o comando com eval.

eval "cd ~$USER"

mudará para o diretório inicial do usuário fornecido pelo nome de usuário na variável USER, desde $USERque não contenha caracteres especiais para o shell (se houver uma chance remota de que isso ocorra, você não deve passá-lo como argumento, evalpois isso seria perigoso ) ou /caracteres e que há uma entrada para esse usuário no banco de dados de usuários do sistema.

Kasperd
fonte
3

Uma maneira alternativa de procurar o diretório inicial de um usuário variável, se você estiver usando um dos shells em que a expansão til ocorre antes da expansão variável, é com getent . Esta ferramenta existe em pelo menos Linux, Solaris e FreeBSD; Não tenho certeza de quão universal é.

$ USER=bloggs
$ getent passwd "$USER" | cut -d: -f6
/home/b/bloggs

Assim como na expansão til, isso pode não dar a mesma coisa que su - $USER -c 'echo $HOME'seria impressa se você tivesse os privilégios para fazer isso.

zwol
fonte
1
Veja também perl -le 'print((getpwnam shift)[7])' -- "$USER"como potencialmente um pouco mais portátil.
Stéphane Chazelas
-2

Como o OP insiste em uma resposta, aqui está.

O comportamento desses comandos (e muitas outras coisas) depende do shell específico que você está usando. A menos que você especifique qual shell específico você usa, provavelmente não é possível dar uma resposta simples.

De fato, se você usar o tcsh, como eu, as duas expressões da pergunta do OP (como está escrito enquanto escrevo isso - não me responsabilizo por edições futuras!) Funcionam perfeitamente. Não sei o que outras conchas farão, já que não as uso. Então, talvez o OP não saiba tanto sobre o que pode ser feito quanto ele pensa :-)

jamesqf
fonte