Bash
將字元串和變數添加到bash腳本中的另一個變數
我嘗試創建一個 bash 腳本來顯示所有可用的本地 IP 地址。由於每個 IP 地址的正常 ping 選項不能快於 1 秒,並且 fping 在 for 循環中執行時顯示太多輸出,我嘗試這樣做:
read -p "Enter Gateway IP Address: " gateway for ip in $(seq 1 254); allips = $allips ${gateway::-1} $ip done fping -c1 -t500 -a $allips > /dev/null
但是每次我嘗試執行這個小腳本時,它都表明
local.sh: line 2: : command not found local.sh: line 4: syntax error near unexpected token `allips' local.sh: line 4: ` allips = $allips ${gateway::-1} $ip'
您的腳本中有許多語法錯誤;我會在最後討論這些。但首先,它看起來有一種更簡單的方法來掃描 /24 子網,使用
fping
’s-g
(generator) 選項。我沒有fping
安裝來測試,但是從文件中,這應該可以工作:#!/bin/bash read -p "Enter Gateway IP Address: " gateway fping -c1 -t500 -a -g "${gateway%.*}.0/24" > /dev/null
該
${gateway%.*}
部分採用輸入的網關 IP,從最後一個“.”開始修剪。(即最後一個八位字節)。所以如果網關是“192.168.0.254”,那就是“192.168.0”。然後該腳本將“.0/24”添加到其中以將“192.168.0.0/24”作為子網字元串。原始腳本中的問題:
- 使用適當的 shebang 行開始您的腳本。一般來說,這將是
#!/bin/bash
或#!/usr/bin/env bash
。您還會看到#!/bin/sh
,但如果您在腳本中使用任何 bash 語法擴展,這可能會導致麻煩。如果您不知道 bash 與普通 sh 語法的微妙之處,請堅持使用 bash shebang。- 您的
for
陳述缺少其do
. 應該是for ip in $(seq 1 254); do
。- bash v3 不允許負字元串索引(例如
${gateway::-1}
)。如果你有 bash 版本 4,那就可以了;如果您有 v3,則需要從字元串長度中減去 1${gateway::${#gateway}-1}
:。或者你可以使用從頭修剪操作符,%
就像我在上面的程式碼中所做的那樣。如果您使用${gateway%.*}
,那將刪除最後一個“。” 以及數字,因此您需要將其添加回來。另一個優點是,如果最後的八位字節超過一位(例如,有些人出於某種原因將他們的路由器設置為 0.254),這也將起作用。- 您幾乎應該總是在變數引用周圍加上雙引號,以避免各種形式的空格、萬用字元等的錯誤解析。在這種情況下,它可能是安全的,但我仍然會避免它。但是在您的腳本中,您指望分詞將每個地址作為單獨的參數傳遞給
fping
. 在 shell 腳本中執行此操作的最佳實踐方法是使用數組而不是普通變數,每個參數都是一個單獨的數組元素。其語法有點混亂,但基本操作如下:args=(arg1 arg2 "arg with spaces") # The parentheses tell bash this is an array for x in list of things; do args+=(additionalarg) # Add elements to array. Both + and () are REQUIRED done somecommand "${args[@]}" # Yes, all those parentheses, brackets, etc are needed
- 您不能在分配中使用空格(除非您引用或轉義它們,在這種情況下它們是分配字元串的一部分)。當您使用
var = something
時,shell 將其視為執行命令var
,使用=
和something
作為參數。所以你的作業應該是這樣的:allips="$allips ${gateway::-1}$ip"
…除了我上面說的,你應該使用一個數組。所以在循環(
allips=()
)之前將其設置為空,然後使用:allips+=("${gateway%.*}.$ip")
然後在循環之後,像這樣使用它:
fping -c1 -t500 -a "${allips[@]}" > /dev/null