String Bash字符串concat不起作用-concat的结果为空

String Bash字符串concat不起作用-concat的结果为空,string,bash,concatenation,String,Bash,Concatenation,我尝试构建一个Git prepare commit msg钩子,它为Git bash(mingw32)提供以下输出: 效果很好 git diff--cached--name status为索引中已更改的每个文件打印\t 但当我这么做的时候 #!/bin/bash git diff --cached --name-status | while read line; do OUTPUT=$OUTPUT$line$':\n - \n'; done echo $OUTPUT 或 $OUTPUT为空 这

我尝试构建一个Git prepare commit msg钩子,它为Git bash(mingw32)提供以下输出:

效果很好

git diff--cached--name status
为索引中已更改的每个文件打印
\t

但当我这么做的时候

#!/bin/bash
git diff --cached --name-status | while read line; do OUTPUT=$OUTPUT$line$':\n - \n'; done
echo $OUTPUT

$OUTPUT
为空

这也很好

COUNTER=0
         while [  $COUNTER -lt 10 ]; do
             TEST+=$COUNTER$':\n'
             let COUNTER=COUNTER+1 
         done
echo $TEST
我做错了什么

已解决

#!/bin/bash
git diff --cached --name-status | { 
while read line; do
    output=$output$var$':\n  - \n'
done
echo "$output" > $1
}

因为您使用的是管道,
while
循环在子shell中运行,所以当该子shell退出时,其变量随之消失。父shell中的
$OUTPUT
变量为空

您必须确保在父shell中构建输出:

while read line; do
    OUTPUT+=$line$':\n - \n'
done < <(git diff --name-status)
echo "$OUTPUT"
或者,在子shell中输出变量

git diff --name-status | { 
    while read line; do OUTPUT+="$line"$':\n - \n'; done
    echo "$OUTPUT"
}
其他说明:

  • 如果要保留所有这些换行符,需要引用“$OUTPUT”
  • 摆脱使用大写变量的习惯:保留那些为shell保留的变量

您根本不需要构建变量
输出。只需在读取输入时写入输出。(使用
printf
比使用
echo
更干净、更标准)


git diff--cached--name status的输出是什么?如果你能把你的问题告诉我们,那会很有帮助。前两个解决方案在mingw32 bash中不起作用。第三个很好,我使用了变量输出,因为我需要将输出写入$1中给出的文件。因此,在循环最终工作之后,我将echo重定向到$1。您可以将循环的输出重定向到文件<代码>同时。。。;做完成>“$1”
@BlackEye,比我的解决方案更好
#!/bin/bash
git diff --cached --name-status | { 
while read line; do
    output=$output$var$':\n  - \n'
done
echo "$output" > $1
}
while read line; do
    OUTPUT+=$line$':\n - \n'
done < <(git diff --name-status)
echo "$OUTPUT"
set +m; shopt -s lastpipe
git diff --name-status | while read line; do OUTPUT+=$line$':\n - \n'; done
echo "$OUTPUT"
git diff --name-status | { 
    while read line; do OUTPUT+="$line"$':\n - \n'; done
    echo "$OUTPUT"
}
git diff --cached --name-status | while read line; do
    printf '%s:\n - \n' "$line"
done