Bash quando usar $ @, “$ @” e $ {1 + “$ @”} [duplicado]

0

tl; dr ... encontrou um script que usa ${1+"$@"} para encaminhar argumentos de linha de comando para outro script. o que exatamente isto faz? Quando você o usa em vez de $@ e "$@" ?

Existe um script de shell simples chamado runhaskell que é distribuído com o ghc no Ubuntu 15.10 (e talvez outros). Eu estou tentando descobrir como substituí-lo com algo que é consciente de caixas de areia cabalas. O script de shell é assim. Parece haver algumas variáveis que não são usadas e um comentário desnecessário do tipo shebang (de uma versão anterior do script?)

#!/bin/bash
exedir="/usr/lib/ghc/bin"
exeprog="runghc"
executablename="$exedir/$exeprog"
datadir="/usr/share"
bindir="/usr/bin"
topdir="/usr/lib/ghc"
#!/bin/sh

exec "$executablename" -f "$bindir/ghc" ${1+"$@"}

Estou tendo problemas para entender a última linha. /usr/lib/ghc/bin/runghc é um executável nativo que runhaskell evidentemente delega, e um dos argumentos que ele transmite é o local do compilador. Ok, não há problema.

O que o ${1+"$@"} faz e quando você deve usá-lo? Meu melhor palpite é que 1 é apenas um teste que sempre é bem-sucedido e que essa construção está sendo usada apenas para passar os argumentos textualmente. Eu lembro que o POSIX requer que $@ e "$@" se comportem de maneira um pouco diferente do que você esperaria, mas não me lembro dos detalhes exatos.

    
por Gregory Nisbet 13.03.2016 / 20:47

1 resposta

2

${var+foo} expande para foo se a variável var estiver definida (mesmo se vazia) e nada de outra forma. Nesse caso, a variável é o primeiro parâmetro posicional, $1 . Portanto, o ${1+"$@"} verifica se $1 está definido e se expande para "$@" de acordo e não é nada diferente.

Quanto a $@ e "$@" , $@ está sujeito a divisão de campo e expansão de nome de arquivo depois de ter expandido para os parâmetros posicionais, enquanto "$@" não é:

$ sh -c 'cd /usr; printf "%s\n" $@' _ 'a b' '*'  
a
b
bin
include
…
$ sh -c 'cd /usr; printf "%s\n" "$@"' _ 'a b' '*'
a b
*

Você quase sempre quer usar "$@" over $@ .

Quanto a ${1+"$@"} vs apenas "$@" , em shells compatíveis com POSIX, ambos teriam o mesmo efeito. De acordo com esta postagem do Stack Overflow :

'Hysterical Raisins', aka Historical Reasons.

Once upon 20 or so years ago, some broken minor variants of the Bourne Shell substituted an empty string "" for "$@" if there were no arguments, instead of the correct, current behaviour of substituting nothing. Whether any such systems are still in use is open to debate.

A seção manual autoconf em Substituições de shell também lida com isso:

There are also portability pitfalls with particular expansions:

$@

One of the most famous shell-portability issues is related to ‘"$@"’. When there are no positional arguments, Posix says that ‘"$@"’ is supposed to be equivalent to nothing, but the original Unix version 7 Bourne shell treated it as equivalent to ‘""’ instead, and this behavior survives in later implementations like Digital Unix 5.0.

Veja também:

por 13.03.2016 / 21:13

Tags