Bash

將字元串和變數添加到bash腳本中的另一個變數

  • January 10, 2018

我嘗試創建一個 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

引用自:https://serverfault.com/questions/891000