Por que 'read -r' ainda obtém apenas a primeira palavra de cada linha?

2

Esta questão está relacionada com minha mais antiga aqui .

Depois que eu finalmente descobri como contornar a saída do git em uma função, agora tenho outro problema. Usando

git clone --progress XYZ &> git_clone.file

escreve como esperado

Cloning to 'someRepository' ...
remote: Counting objects: 2618, done.
remote: Compressing objects: 100% (14/14), done.
remote: Total 2618 (delta 2), reused 12 (delta 1), pack-reused 2603
Received objects: 100% (2618/2618), 258.95 MiB | 4.39 MiB/s, Done.
Resolving Differences auf: 100% (1058/1058), Done.
Check Connectivity ... Done.

em git_clone.file .

Agora eu não quero redirecionar a saída para um arquivo, mas para uma função, então eu uso

function PrintInfo(){
    tput el
    echo 
    <Print ProgressBar> 
    #For further details about this see 
    # https://askubuntu.com/questions/988403/bash-pass-command-output-to-function-in-realtime
}

git clone --progress XYZ |& {
    while read -r line
    do
        PrintInfo $line
    done
}

Agora eu esperaria receber

Cloning to 'someRepository' ...
remote: Counting objects: 2618, done.
remote: Compressing objects: 100% (14/14), done.
remote: Total 2618 (delta 2), reused 12 (delta 1), pack-reused 2603
Received objects: 100% (2618/2618), 258.95 MiB | 4.39 MiB/s, Done.
Resolving Differences auf: 100% (1058/1058), Done.
Check Connectivity ... Done.

linha a linha impressa e na parte inferior minha barra de progresso como descrito em minha outra pergunta . Mas em vez disso eu só recebo

Cloning
remote:
remote:
Received
...

e assim por diante. Eu já tentei todas as formas de IFS like

... while IFS= read -r ...

... while IFS='' read -r ...

... while IFS="\n" read -r ...

mas nenhum deles resolve esse problema.

Como posso ler a linha completa da saída?

    
por derHugo 23.12.2017 / 23:24

1 resposta

3

O problema é divisão de palavras . Para resolvê-lo, substitua:

PrintInfo $line

Com:

PrintInfo "$line"

Explicação

Considere:

PrintInfo $line

Antes de executar, PrintInfo , o shell expandirá $line e executará ambos divisão de palavras e expansão de nome de caminho .

Vamos dar um exemplo simples, começando por definir uma função:

$ PrintInfo() { echo "1= 2= 3="; }

Agora, vamos executar a função:

$ line="one two three"
$ PrintInfo $line
1=one 2=two 3=three

Acima, a divisão de palavras fez com que PrintInfo visse três argumentos.

Se você quiser que PrintInfo veja apenas um argumento, use:

$ PrintInfo "$line"
1=one two three 2= 3=

A expansão do nome do caminho também é um problema em potencial. Considere um diretório com esses arquivos:

$ ls
file1  file2  file3

Agora, vamos executar nossa versão de PrintInfo novamente:

$ line='file?'
$ PrintInfo $line
1=file1 2=file2 3=file3

Como ? é um caractere glob válido, o shell procura substituir file? por nomes de arquivos. Para evitar essa surpresa, use aspas duplas:

$ PrintInfo "$line"
1=file? 2= 3=

Resumo

Exceto nos casos em que você deseja explicitamente divisão de palavras ou expansão de nome de caminho , variáveis de shell devem estar sempre entre aspas duplas .

    
por John1024 23.12.2017 / 23:29