我在通过管道传输到正则表达式的 bash 脚本中使用 perl.如何在管道流中设置变量?



我创建了一个bash脚本,该脚本在包含不同git本地存储库的多台计算机上运行。 它测试了许多条件,并告诉我存储库是否有未提交的文件、未跟踪的文件,并且有一个测试特别告诉我,本地的提交次数领先于或落后于远程。 脚本的问题在于它不会返回或设置"ok"标志,如果一切都同步,我用它来回显"ok"消息。 所以,我得到的消息是它领先或落后,但随后得到"确定"消息。 这是脚本中超前或后的部分,我看不出如何让它以某种方式设置 ok = false。

git fetch>/dev/null && git branch -v |
perl -wlne'
print "$ENV{reponame} [$1] --> $3 $2"
if /^..(S+)s+([a-f0-9]+)s+([(?:ahead|behind)s+d+])/
' |
while IFS= read -r MOD; do
ok=false
printf ' %sn' "$MOD"  # Replace with code that uses $MOD
done
if $ok; then
echo " OK --> $reponame [$br] $rev"
fi 

我从另一个脚本复制了这个,并不真正理解 IFS = read -r MOD; 部分,我认为可能会设置标志,但它没有发生。

这是我得到的输出:

bin [develop] --> [behind 1] 026e1ad
OK --> bin [develop] 026e1ad
OK --> notes [develop] 4cd077f
OK --> indecks [develop] e6b4293
OK --> queue [develop] 5469679
OK --> frameworks [master] 05fedb6
OK --> dashboard [isolate] f8b1101
OK --> nodejs [develop] 5af2ea7
OK --> perl-forth [master] 45cc837
OK --> blog [master] c19edfd

请注意,对于垃圾箱,我得到:

bin [develop] --> [behind 1] 026e1ad
OK --> bin [develop] 026e1ad

我宁愿在后面 1 之后不要那么好! 另一个脚本检查左栏中是否有任何不正常,并向我发送电子邮件。

使用 perl 和所有管道,如何在打印之前设置 ok 变量?

在大多数 shell 实现中,管道中的所有进程都在子 shell 中运行。 在这种情况下,你在管道的末端运行一个 while 循环,所以它(而且单独(在子 shell 中。 无论您是否将ok设置为false,它对 if 块都没有影响,因为它运行主 shell,它不会从子 shell 继承变量。

zsh 和 AT&T ksh(但不是其他 ksh 实现(执行主 shell 中的最后一个命令,而不是子 shell。 POSIX 允许这两种行为,但 bash 行为在 shell 中更为常见。

处理此问题的最简单方法是在子外壳中运行您感兴趣的整个命令:

git fetch>/dev/null && git branch -v |
perl -wlne'
print "$ENV{reponame} [$1] --> $3 $2"
if /^..(S+)s+([a-f0-9]+)s+([(?:ahead|behind)s+d+])/
' |
(while IFS= read -r MOD; do
ok=false
printf ' %sn' "$MOD"  # Replace with code that uses $MOD
done
if $ok; then
echo " OK --> $reponame [$br] $rev"
fi) 

这会将使用ok变量的两个部分放在同一个子 shell 中,因此您可以对其进行修改,它将产生影响。

最新更新