Bash 字符串连接不起作用 - 连接结果为空

Bash string concat does not work - Result of concat is empty

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

<file1>:
 -
<file2>:
 - 
...

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

效果很好

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

但是当我这样做的时候

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

#!/bin/bash
git diff --cached --name-status | while read line; do 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" > 
}

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

您必须确保在父级中建立 OUTPUT shell:

while read line; do
    OUTPUT+=$line$':\n - \n'
done < <(git diff --name-status)
echo "$OUTPUT"

或使用"lastpipe"设置为运行当前管道的最后一个命令shell(作业控制需要关闭)

set +m; shopt -s lastpipe
git diff --name-status | while read line; do OUTPUT+=$line$':\n - \n'; done
echo "$OUTPUT"

或者,输出subshell

中的变量
git diff --name-status | { 
    while read line; do OUTPUT+="$line"$':\n - \n'; done
    echo "$OUTPUT"
}

其他说明:

  • 如果你想保留所有这些换行符,你需要引用 "$OUTPUT"
  • 改掉使用大写变量的习惯:保留那些为 shell.
  • 保留的

您根本不需要建立变量 OUTPUT。只需在读取输入时写入输出即可。 (使用 printf 比使用 echo 更简洁、更标准。)

git diff --cached --name-status | while read line; do
    printf '%s:\n - \n' "$line"
done