desenv-web-rp.com

Qual é o significado de IFS = $ '\ n' no script bash?

No início de um script Shell do bash, está a seguinte linha:

IFS=$'\n'

Qual é o significado por trás dessa coleção de símbolos?

180
Abdul Al Hazred

IFS significa "separador de campo interno". É usado pelo Shell para determinar como fazer a divisão do Word, i. e como reconhecer os limites do Word.

Tente isso em um shell como o bash (outros shells podem lidar com isso de maneira diferente, por exemplo, zsh):

mystring="foo:bar baz rab"
for Word in $mystring; do
  echo "Word: $Word"
done

O valor padrão para IFS consiste em caracteres de espaço em branco (para ser mais preciso: espaço, tabulação e nova linha). Cada caractere pode ser um limite do Word. Portanto, com o valor padrão IFS, o loop acima será impresso:

Word: foo:bar
Word: baz
Word: rab

Em outras palavras, o Shell pensa que espaço em branco é um limite do Word.

Agora, tente definir IFS=: antes de executar o loop. Desta vez, o resultado é:

Word: foo
Word: bar baz rab

Agora, o Shell divide mystring em palavras também - mas agora, trata apenas dois-pontos como o limite da Palavra.

O primeiro caractere de IFS é especial: é usado para delimitar palavras na saída ao usar o especial $* variable (exemplo extraído do Advanced Bash Scripting Guide , onde você também pode encontrar mais informações sobre variáveis ​​especiais como essa):

$ bash -c 'set w x y z; IFS=":-;"; echo "$*"'
w:x:y:z

Comparado a:

$ bash -c 'set w x y z; IFS="-:;"; echo "$*"'
w-x-y-z

Observe que nos dois exemplos, o Shell ainda tratará todos os caracteres :, - e ; como limites do Word. A única coisa que muda é o comportamento de $*.

Outra coisa importante a saber é como o chamado "espaço em branco do IFS" é tratado . Basicamente, assim que IFS inclui caracteres de espaço em branco, o espaço em branco à esquerda e à direita é retirado da string a ser dividida antes de processá-la e uma sequência de caracteres de espaço em branco consecutivos também delimita campos. No entanto, isso se aplica apenas aos caracteres de espaço em branco que estão realmente presentes em IFS.

Por exemplo, vejamos a string "a:b:: c d " (espaço à direita e dois caracteres de espaço entre c e d).

  1. Com IFS=: seria dividido em quatro campos: "a", "b", "" (sequência vazia) e " c d " (novamente, dois espaços entre c e d). Observe o espaço em branco à esquerda e à direita no último campo.
  2. Com IFS=' :', seria dividido em cinco campos: "a", "b", "" (sequência vazia), "c" e "d". Nenhum espaço em branco à esquerda e à esquerda em qualquer lugar.

Observe como vários caracteres de espaço em branco consecutivos delimitam dois campos no segundo exemplo, enquanto vários dois pontos consecutivos não o fazem (já que não são caracteres de espaço em branco).

Quanto a IFS=$'\n', Aquilo é um ksh93 sintaxe também suportada por bash, zsh, mksh e FreeBSD sh (com variações entre todos os shells). Citando a página de manual do bash:

Palavras da forma $ 'string' são tratadas especialmente. O Word se expande para "string", com caracteres de escape com barra invertida substituídos conforme especificado pelo padrão ANSI C.

\n é a sequência de escape de uma nova linha, então IFS acaba sendo definido como um único caractere de nova linha.

216
Tblue

Dentro de aspas simples, alguns caracteres são avaliados especialmente. Por exemplo, \n é traduzido para a nova linha.

Portanto, essa linha específica atribui nova linha à variável IFS. O IFS, por sua vez, é uma variável especial no bash: Internal Field Separator. Como man bash diz,

é usado para dividir o Word após a expansão e dividir linhas em palavras com o comando interno read. O valor padrão é <space><tab><newline>.

23
choroba

Abreviado, IFS=$'\n' atribuir nova linha \n para a variável IFS.

$'string' construct é um mecanismo de citação usado para decodificar ANSI C como seqüências de escape. Essa sintaxe vem de ksh93, e era portátil para o Shell moderno como bash, zsh, pdksh, busybox sh.

Essa sintaxe não é definida pelo POSIX, mas foi aceita para SUS edição 7 .

15
cuonglm