bash 函數內變數創建的行為

bash 函數內變數創建的行為

我正在使用下面的函數來增加外部腳本。其主要目的只是從 ifconfig 和 ping 測試輸出傳回一些資料。我試圖使用變數將它們設置在同一個函數中,只是為了執行一些其他“管道”並將它們與其他資訊再次連接起來。但我得到了這種行為。基本上,我想做的是:

    > for i in $(ifconfig | grep "inet addr" | tr -s " " | cut -d" " -f 3 | cut -d: -f2) ; do ping -c1 $i | grep packet | a=`echo $i-$(cut -d,
    -f3)` | echo $a; done  
4  
4  
4  
4

如您所見,每次迭代都會傳回數字 4。

如果我只是刪除變數歸因,我會得到我期望首先在變數“a”中設定的輸出:

> for i in $(ifconfig | grep "inet addr" | tr -s " " | cut -d" " -f 3 | cut -d: -f2) ; do ping -c1 $i | grep packet | echo $i-$(cut -d, -f3); done
10.0.2.15- 0% packet loss
192.168.0.2- 0% packet loss
10.0.2.100- 0% packet loss
127.0.0.1- 0% packet loss
  • 為什麼我在第一個函數程式碼執行中得到數字 4 作為輸出?
  • 如何在同一函數內設定變數並在某些管道後再次回顯它?那可能嗎?

此致 !

答案1

 for i in $(...) ; do ... | a=`...` | echo $a; done

為什麼我在第一個函數程式碼執行中得到數字 4 作為輸出?

因為a=`...`echo $a是在不同的子shell/子進程中執行的。a=1; a=3 | echo $a1在任何 shell 中列印。無法將變數從子 shell 傳遞到其父 shell。

如何在同一函數內設定變數並在某些管道後再次回顯它?那可能嗎?

不可以。

答案2

如果您使用重組管道的最後一部分,sed我認為您可以獲得您想要的東西。該腳本匹配整個標準輸入,並將其替換為後跟的sed值和輸出的第三個欄位(來自標準輸入)。例如,$i-ping

$ for i in $(ifconfig | grep "inet addr" | tr -s " " | cut -d" " -f3 | cut -d: -f2); do \
    ping -c1 $i | grep packet | cut -d, -f3 | sed "s/\(.*\)/$i - \\1/"; \
done
123.145.167.189 -  0% packet loss
127.0.0.1 -  0% packet loss

相關內容