簡體   English   中英

我在 bash 腳本中使用 perl 來傳遞到正則表達式。 如何在管道 stream 中設置變量?

[英]I use perl in a bash script that pipes to a regular expression. How do I also set a variable in the piped stream?

我創建了一個 bash 腳本,該腳本在包含不同 git 本地存儲庫的多台機器上運行。 它測試了許多條件並告訴我存儲庫是否有未提交的文件、未跟蹤的文件,特別是一項測試告訴我本地在提交數量上領先還是落后於遠程。 腳本的問題是它沒有返回或設置一個“ok”標志,如果一切都同步,我用它來回顯“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 ' %s\n' "$MOD"  # Replace with code that uses $MOD
        done
        if $ok; then
              echo " OK --> $reponame [$br] $rev"
        fi 

我從另一個腳本中復制了這個,並不真正理解 IFS = read -r MOD; 我認為可能會設置標志的部分,但它沒有發生。

這是我得到的 output:

 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 我得到:

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

在后面 1 之后,我寧願沒有得到那個 OK。另一個腳本檢查左列中的任何非 OK 並向我發送電子郵件。

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

在大多數 shell 實現中,管道中的所有進程都在子 shell 中運行。 在這種情況下,您在管道末端運行了一個 while 循環,因此它(並且僅它一個)位於子 shell 中。 無論您是否將ok設置為false ,它對 if 塊都沒有影響,因為它運行的是主 shell,它不會從子 shell 繼承變量。

zsh 和 AT&T ksh(但不是其他 ksh 實現)在主 shell 而不是子 shell 中執行最后一個命令。 POSIX 允許任何一種行為,但 bash 行為在 shell 中更為常見。

處理此問題的最簡單方法是在子 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 ' %s\n' "$MOD"  # Replace with code that uses $MOD
        done
        if $ok; then
              echo " OK --> $reponame [$br] $rev"
        fi) 

這會將使用ok變量的兩個部分放在同一個子 shell 中,因此您可以對其進行修改,它會產生效果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM