为什么`read -r`仍然只能获取每行的第一个单词?

为什么`read -r`仍然只能获取每行的第一个单词?

这个问题与我的大儿子在这里

在我终于找到如何绕过 git 的输出进入函数之后,我现在又遇到了另一个问题。使用

git clone --progress XYZ &> git_clone.file

按预期写入

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.

进入git_clone.file

现在我不想将输出重定向到文件而是重定向到函数,因此我使用

function PrintInfo(){
    tput el
    echo $1
    <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
}

现在我期望得到

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.

逐行打印并在底部打印我的进度条,如所述我的另一个问题但我得到的只是

Cloning
remote:
remote:
Received
...

等等。我已经尝试过各种形式IFS

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

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

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

但它们都无法解决这个问题。

我怎样才能读出完整的输出行?

答案1

问题是单词拆分。要解决此问题,请替换:

PrintInfo $line

和:

PrintInfo "$line"

解释

考虑:

PrintInfo $line

在执行之前PrintInfo,shell 将扩展$line并执行单词拆分路径名扩展

让我们举一个简单的例子,首先定义一个函数:

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

现在,让我们执行该函数:

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

在上文中,单词拆分导致PrintInfo看到三个论点。

如果只想PrintInfo查看一个参数,请使用:

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

路径名扩展也是一个潜在的问题。考虑包含以下文件的目录:

$ ls
file1  file2  file3

现在,让我们PrintInfo再次运行我们的版本:

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

由于?是有效的 glob 字符,因此 shell 会将其替换file?为文件名。为了避免这种意外,请使用双引号:

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

概括

除非你明确想要单词拆分或者路径名扩展shell 变量应始终放在双引号内

相关内容