Env. variável ecoou diferente com "e sem"

0

Estou aprendendo sobre o bash shell e variáveis de ambiente.

Eu testei echo um env. var cercado por citações e sem elas (eu coloco como aparece no meu terminal):

user@pc:~$ echo "$BASE_DEPENDENCIES"
build-essential \
                   cmake           \
                   debhelper       \
                   mesa-utils      \
                   cppcheck        \
                   xsltproc        \
                   python-psutil   \
                   python          \
                   bc              \
                   netcat-openbsd  \
                   gnupg2          \
                   net-tools       \
                   locales
user@pc:~$ echo $BASE_DEPENDENCIES
build-essential \ cmake \ debhelper \ mesa-utils \ cppcheck \ xsltproc \ python-psutil \ python \ bc \ netcat-openbsd \ gnupg2 \ net-tools \ locales

O primeiro tem novas linhas e espaços. O segundo é apenas uma linha.

Por que isso acontece?

A propósito, meu sistema é um Ubuntu 17.04.

    
por VansFannel 18.10.2017 / 19:27

3 respostas

2

Há uma sequência de expansões que o bash faz em entradas:

The order of expansions is: brace expansion; tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution (done in a left-to-right fashion); word splitting; and filename expansion.

A versão sem aspas permite divisão de palavras (com ênfase):

The shell scans the results of parameter expansion, command substitution, and arithmetic expansion that did not occur within double quotes for word splitting.

... e com um valor padrão de $IFS , isso significa que build-essential \(newline)(other spaces)cmake ... se transforma em várias palavras:

  • build-essential
  • \
  • cmake
  • ...

... removendo efetivamente o caractere de nova linha, bem como todos, mas um de cada caractere de espaço.

A citação da variável impede a divisão de palavras (entre outras coisas).

Leitura adicional:

por 18.10.2017 / 20:04
1

O shell separa parâmetros para comandos com 1 ou mais espaços em branco (ou seja, espaço, tabulação, nova linha). Quando você não incluir cotações, o valor de $BASE_DEPENDENCIES será expandido para N parâmetros. echo pega todos os seus parâmetros e imprime cada um deles separados por espaços simples, então você tem:

build-essential<space>\<space>cmake<space>\...

As citações anulam a delimitação do espaço; tudo dentro das aspas é passado como um único argumento. Nesse caso, o valor de $BASE_DEPENDENCIES recebe um parâmetro 1 para echo . echo , em seguida, imprime que um parâmetro foi fornecido (espaços, novas linhas, etc. intactos).

Para entender melhor, considere esta função de shell simples, que é equivalente a um comando neste caso:

foo() {
    for i in "${@}"; do
        echo "->'${i}'"
    done
}

Digamos que eu tenha uma variável parecida com:

x="    1         2 3    4   "

Sem aspas, recebo 4 argumentos:

$ foo $x
->'1'
->'2'
->'3'
->'4'

Com aspas, recebo apenas uma:

$ foo "$x"
->'    1         2 3    4   '
    
por 18.10.2017 / 20:02
0

Isso porque as citações preservam os espaços em branco. Compare com isso:

# a=$(cal)
# echo $a
October 2017 Su Mo Tu We Th Fr Sa 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
# echo "$a"
    October 2017      
Su Mo Tu We Th Fr Sa  
 1  2  3  4  5  6  7  
 8  9 10 11 12 13 14  
15 16 17 18 19 20 21  
22 23 24 25 26 27 28  
29 30 31  

Primeiro, a saída do comando cal é armazenada em a . Então é impresso sem e com citações. Como você pode ver, as citações preservam os espaços em branco, enquanto nenhuma citação divide o texto em tokens , que são separados por espaço.

    
por 18.10.2017 / 20:05