我有一个案例:在WordPress项目中,我应该创建一个脚本来更新插件并将源更改提交到单独的分支。在执行此操作时,我遇到了一个奇怪的问题。
输入变量:
akimset,4.0.3
all-in-one-wp-migration,6.71
我想做的是遍历此变量的每一行
while read -r line; do
echo $line
done <<< "$variable"
这一段代码工作得很好,但是当我添加了docker-compose逻辑后,一切开始变得怪异
while read -r line; do
docker-compose run backend echo $line
done <<< "$variable"
现在只执行了一行,并且此脚本以0退出并停止了迭代之后。我找到了解决方法:
echo $variable > file.tmp
for line in $(cat file.tmp); do
docker-compose run backend echo $line
done
,并且效果很好,并且迭代每行。现在我的问题是:为什么? ZSH和Shell脚本编写可能有点繁琐,并且在这种情况下运行对我来说并不是什么新鲜事,但是我想知道为什么成功执行的脚本会破坏输入流。
答案 0 :(得分:0)
大约在一年前,我遇到了一个几乎相同的问题,尽管外壳是bash
(命令/问题也稍有不同,但是它适用于您的问题)。我最终在zsh
中编写了脚本。
我不确定发生了什么,但这实际上不是退出代码(您可以通过运行以下命令进行确认):
variable=$'akimset,4.0.3\nall-in-one-wp-migration,6.71'
while read line; do docker-compose run backend print "$line"; print "$?"; done <<<($variable)
...产生了...
(akimset,4.0.3
0
(我不确定(
的来源,也许解决这个问题可以回答为什么发生此问题)
for line in "${(f)variable}"; do
docker-compose run backend echo "$line"
done
(f)
标志告诉zsh
换行。 "${(f)variable"
用引号引起来,这样任何空白行都不会丢失。如果您要包含要不转换为相应值的escap序列(从变量读取文件内容时经常需要的值),请设置标志(fV)
答案 1 :(得分:0)
这个问题
while read -r line; do
docker-compose run backend echo $line
done <<< "$variable"
是docker分配了伪TTY。在第一次执行docker-compose run(第一个循环)后,它将使用下一行作为输入来访问终端。
您必须将-T参数传递给'docker-compose run'命令,以避免docker分配伪TTY。然后,一个有效的代码是:
while read -r line; do
docker-compose run -T backend echo $line
done < $(variable)
以上解决方案适用于docker版本18和docker-compose版本1.17。对于较新的版本,参数-T不起作用,但是您可以尝试:
答案 2 :(得分:0)
我能够通过使用不同的循环来解决相同的问题:
for line in $(cat $variable)
do
docker-compose run backend echo $line
done