[原創] 用 shell 來計算 network 跟 broadcast

我來加一下注解好了:

  1. #!/bin/bash 

  2. # 將參數值裡的非數字全部換成空白鑑
  3. all=(${@//[!0-9]/ }) 

  4. # 要是處理過的參數量不是 8 個的話... 送出錯誤信息,告知命令可接受的參數格式。並退出。
  5. [ "${#all[@]}" != "8" ] && { 
  6.         echo "Usage: " 
  7.         echo "${0##*/} ip.ip.ip.ip/mask.mask.mask.mask" 
  8.         exit 1 


  9. # 定義一個 get_add 的 function 
  10. get_addr () { 

  11. # 要是讀進的第一個 function 參數為 -b ,則設定 op, op1, 與 arg 的變量,以供後面的 $(( $1 $op ($5 $op1 $arg) )) 計算用。
  12.         if [ "$1" = "-b" ]; then 
  13. # 其結則為 $(( $1 | ($5 ^ 255) )),也就是逐個算出 broadcast address 。
  14.                 op='|'; op1='^'; arg='255' 
  15. # 然後用 shift 拿掉這個 -b 。
  16.                 shift 

  17. # 若沒有 -b 參數,則只定義 op 變量。然則,$(( $1 $op ($5 $op1 $arg) )) 的實際算式就變成 $(( $1 & $5)),這會逐個算出 network address 。
  18.         else 
  19.                 op='&' 
  20.         fi 

  21. # 取消變量 address ,以免影嚮其後於 while loop 的運算。
  22.         unset address 

  23. # 假如能讀到第 5 個參數,才進入 while loop,否則離開。
  24.         while [ "$5" ]; do 

  25. # 跟據前面的 -b 參數,來決定要算出 broadcast 還是 network 。因為前 4 個參數是 ip 後 4 個是 mask ,因此第一個參數跟第五個參數來算就能得出第一組 ip/mask 的計算結果。
  26.                 num=$(( $1 $op ($5 $op1 $arg) )) 
  27. # 再拿掉第一個參數,這可讓下一次 looping 計算下一組 ip/mask 。當 shift 4 次之後,while loop 就可結束。
  28.                 shift 
  29. # 將每次的計算結果擴充在 address 變量中。(注意:如此的話,最後結果前面會有一個小數點,我們後面再處理)
  30.                 address="$address.$num" 
  31.         done 


  32. # 跑 function 來計算 network address :
  33. get_addr ${all[@]} 
  34. # echo -e 可以用 \t 送出一個 <tab> 鍵。${address#.} 則是拿掉最前面的小點。 
  35. echo -e "network:\t${address#.}" 

  36. # 跑 function 來計算 broadcast address :
  37. get_addr -b ${all[@]} 
  38. echo -e "broadcast:\t${address#.}"
复制代码


-----------
補充,若不用 while loop + shift 來逐次計算 $1 與 $5 的話,我們也可以一次過將 4 組 ip/mask 計算出來:
num1=$(( $1 $op ($5 $op1 $arg) )) 
num2=$(( $2 $op ($6 $op1 $arg) )) 
num3=$(( $3 $op ($7 $op1 $arg) )) 
num4=$(( $4 $op ($8 $op1 $arg) )) 
address=$num1.$num2.$num3.$num4

還有,我的一個朋友,用 awk 來寫也行哦:
  1. #!/bin/bash

  2. G_network () {
  3. echo $@ | awk 'BEGIN{FS="[./]";OFS="."}
  4.     END{
  5.         print and($1,$5),and($2,$6),and($3,$7),and($4,$8)
  6.     }'
  7. }

  8. G_broadcast () {
  9. echo $@ | awk 'BEGIN{FS="[./]";OFS="."}
  10.     END{
  11.         print or($1,xor($5,255)),or($2,xor($6,255)),or($3,xor($7,255)),or($4,xor($8,255))
  12.     }'
  13. }

  14. ###
  15. # main
  16. ###
  17. ALL_IP=192.168.23.32/255.255.252.0
  18. G_network $ALL_IP
  19. G_broadcast $ALL_IP
复制代码