在 Bash 脚本中将字符串和变量添加到另一个变量

在 Bash 脚本中将字符串和变量添加到另一个变量

我尝试创建一个 bash 脚本来显示所有可用的本地 IP 地址。由于常规 ping 选项每个 IP 地址的执行速度不能快于 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'

答案1

您的脚本中有许多语法错误;我将在最后检查这些错误。但首先,似乎有一种更简单的方法来扫描 /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陈述缺少了 its do。应该是for ip in $(seq 1 254); do

  • bash v3 不允许负字符串索引(例如${gateway::-1})。如果您使用的是 bash 版本 4,那么这种方法可行;如果您使用的是 v3,则需要从字符串长度中减一:${gateway::${#gateway}-1}。或者,您可以使用 trim-from-end 运算符,%就像我在上面的代码中所做的那样。如果您使用${gateway%.*},那么它将删除最后一个“。”以及数字,因此您需要将其添加回来。另一个优点是,如果最后的八位字节多于一位数字(例如,出于某种原因,有些人将他们的路由器放在 .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
    

相关内容