entendendo o valor padrão do IFS

8

No meu GNU bash versão 4.2.8, o IFS tem um valor padrão de espaço, tab e feed de linha por padrão:

usr@T42 ~ $ echo -n "$IFS" | hexdump -C
00000000  20 09 0a                                          | ..|
00000003
usr@T42 ~ $ 

Existe algum motivo para esse IFS padrão? Além disso, quais utilitários usam o IFS além do bash read ?

    
por Martin 20.03.2014 / 12:50

1 resposta

12

A variável IFS é usada toda vez que o shell executa uma tarefa chamada divisão de palavras . Os casos mais comuns em que isso é usado são após a expansão do parâmetro (por exemplo, $var ) ou a substituição de comando (por exemplo, $(some-command) ou os backticks reprovados) em um comando. Aqui, se a expansão contiver qualquer caractere IFS , ela será dividida em diferentes 'palavras' antes que o comando seja processado. Efetivamente, isso significa que esses caracteres dividem o texto substituído em argumentos diferentes (incluindo o nome do comando, se a variável for especificada primeiro).

Assim, o motivo para o valor padrão de IFS ser espaço, tabulação e nova linha é que esses são os caracteres de espaço em branco que normalmente seriam esperados para dividir uma palavra.

Uma maneira de impedir a divisão de palavras é usar aspas duplas em torno da expansão ( "$var" ) - na verdade, você fez isso em sua pergunta. Se você não fez isso, não haveria saída de echo , pois não teria argumentos, apenas caracteres dividindo argumentos.

Note também que dois locais onde a divisão de palavras não acontece após a expansão do parâmetro são com atribuição de variáveis (por exemplo, var=$othervar e var=$(somecommand) está ok) e dentro da construção [[ ]] ( [[ $var = $othervar ]] está ok, mas [ $var = $othervar ] deve ser citado).

Finalmente, como um homem sábio uma vez apontou para mim, um equívoco comum é que a prevenção da divisão de palavras é a única razão para citar uma variável. Não é, a citação também previne expansão de nome de caminho ou glob como é mais comumente conhecido. Se uma variável contiver caracteres glob como * , eles poderão ser expandidos em nomes de arquivos quando a variável for usada sem aspas em um comando. Por exemplo, considere:

var=*
echo $var

Isto irá mostrar os nomes dos arquivos no diretório atual.

Como Stephane aponta abaixo , a ordem dos caracteres dentro de IFS é significativa ao expandir "$*" . Na página bash man:

"$*" is equivalent to "$1c$2c...", where c is the first character of the value of
the IFS variable.  If IFS is unset, the parameters are separated by spaces.  If
IFS is null, the parameters are joined without intervening separators.

Para mais exemplos de divisão de palavras, consulte esta resposta - link

    
por 20.03.2014 / 13:17