PS1 = '$ (pwd)' porque isso funciona e por que isso é diferente de PS1 = $ (pwd)

17

Por que quando eu insiro este comando, o prompt muda para o meu diretório?

PS1='$(pwd)'

Estou usando aspas simples, o que significa que não há interpolação, a.k.a echo '$(pwd)' —— → $(pwd)

Além disso, digamos que esclarecemos por que isso funciona ... por que ele está funcionando de maneira diferente de PS1=$(pwd) ? (sem citações)

Por diferentes, quero dizer que, se eu usar as aspas, o prompt continuará mudando para o meu diretório atual enquanto eu navego pelo terminal. Mas se eu não usar aspas, o prompt sempre permanecerá no diretório em que eu estava quando inseri o comando PS1=$(pwd)

por quê?

    
por HashWizard 22.02.2017 / 22:19

3 respostas

29

Quando você simplesmente atribui um valor a uma variável, a expressão $(...) é avaliada, a menos que esteja entre aspas simples (ou com escape de barra invertida). Para entender, tente e compare estes dois:

A=$(pwd)
echo "$A"
B='$(pwd)'
echo "$B"

O valor de A torna-se imediatamente a string /home/yourusername e, obviamente, não é lembrado de onde essa string vem, ela permanece a mesma, mesmo que você altere o diretório. O valor de B , no entanto, torna-se a string literal $(pwd) sem ser interpretado.

Agora, no valor de PS1 , algo especial acontece: sempre que o prompt é impresso, certas construções especiais são interpretadas, por exemplo, a substituição do comando $(...) é executada exatamente como aconteceu acima na atribuição à variável A . Obviamente se seu PS1 contiver a string literal do seu diretório home (como acima com A ), então não há como alterar. Mas se ela contiver a string $(pwd) (como acima com B ), ela será avaliada sempre que o prompt for impresso e, portanto, o diretório real for exibido.

    
por 22.02.2017 / 22:47
14

No bash e no zsh, o valor de PS1 não é usado como um prompt como está, sofre algumas expansões. As regras diferem para os dois shells, mas em ambos os casos, uma das etapas é executar expansões “dólar” (substituição de variáveis, substituições de comandos, avaliação aritmética) com a mesma sintaxe que na sintaxe normal do shell ( $VARIABLE , ${VARIABLE} , $(COMMAND) ou 'COMMAND' , $((EXPRESSION)) , $[EXPRESSION] ).

  • No bash, a expansão em dólar é ativada por padrão, mas pode ser desativada com shopt -u promptvars .
  • Em zsh, a expansão em dólar está desativada por padrão, mas muitas pessoas (e a maioria das estruturas de configuração encontradas na Web) a ativam com setopt prompt_subst .

Com o dólar expandido no prompt ativado, PS1='$(pwd)' define PS1 para o valor de 6 caracteres $(pwd) e, portanto, faz com que $(pwd) seja substituído e, portanto, o comando pwd seja executado, cada tempo o shell exibe um novo prompt. Por outro lado, PS1=$(pwd) define PS1 para qualquer que seja o diretório de trabalho atual do shell no momento. Se você tivesse a expansão do dólar desativada, então PS1='$(pwd)' faria com que o prompt fosse a string literal $(pwd) .

Observe que existem maneiras mais convenientes de obter o diretório de trabalho no prompt:

  • No bash, com um escape de barra invertida como \w , que abrevia seu diretório pessoal para ~ e pode ser cortado pela configuração de PROMPT_DIRTRIM .
  • Em zsh, com um escape percentual , como %/ ou %~ ( %/ é o mesmo que $PWD , %~ abrevia diretórios iniciais), que pode ter uma configuração de recorte.
  • Em qualquer shell (e qualquer outro shell estilo Bourne), $PWD é equivalente a $(pwd) : você não precisa executar um subprocesso para obter o diretório de trabalho atual.
por 23.02.2017 / 00:17
7

Porque sem as aspas, o $ (pwd) é avaliado quando o PS1 é definido. Com as citações, a avaliação de $ (pwd) é adiada até que o prompt seja exibido.

Sem as aspas, PS1 é definido para o diretório atual no momento em que PS1 é definido. Com as aspas simples, PS1 é definido como $ (pwd), o que significa que avaliará e imprimirá o directoy atual toda vez que o prompt for exibido.

    
por 22.02.2017 / 22:49