1

范围

我正在开发一个 bash 脚本,用于处理重复性任务,将 wlan 接口置于监控模式、进出监控模式,并通过每个步骤显示相关信息。

我开始了这样的事情:

wx="wlan${1}"
wxm="${wx}mon"

# $wx
echo "$wx"
echo -n "stop $wxm if up....";airmon-ng stop $wxm  &> /dev/null; echo " done.";
echo -n "bringing down $wx if up....";ifconfig $wx down  &> /dev/null; echo " done.";
echo -n "changing mac to random....";macchanger -r $wx  &> /dev/null; echo " done.";
echo "mac-adresses randomized"
echo -n "bringing up $wx....";ifconfig $wx up&> /dev/null; echo " done.";
echo -n "putting $wx in monitor mode....";airmon-ng start $wx  &> /dev/null; echo " done.";
echo "$wxm successfully put in monitor mode"
wait

我尝试了不同的方法来导入可用的 wlan-nics,并在朋友的帮助下,最终使用 find 获得了这个功能

function setup_if() {
  local wx="${1}"
  local wxm="${wx}mon"

  echo "setting up: $wx..."
  run_cmd airmon-ng stop $wxm &&
    run_cmd ifconfig $wx down &&
    run_cmd macchanger -r $wx &&
    run_cmd ifconfig $wx up &&
    run_cmd airmon-ng start $wx
  wait
}

for interface in $(find /sys/class/net -name 'wlan*'); do
  interface=$(basename ${interface})
  setup_if ${interface}  || echo "FAILED: ${interface} $previous_command"
done

我被卡住的地方

现在,对于下一步,我想打印一些有关 wlan 状态的有用信息,例如cat /sys/class/net/wlan*/addressiwconfig |grep --regexp wlan

最后,我想将我的操作网卡导出到另一个脚本,以使用 airodump-ng 捕获流量,例如airodump-ng -w /root/pcap/air_capture -c 1,4,6,8,11 $all_operating_wlans

问题:

  1. 我如何为所有检测到的 wlan 创建唯一变量,例如 $w1、$w2 等。我还没有弄清楚如何通过它,find /sys/class/net -name 'wlan?mon'因为它是需要多个变量的几行输出。

  2. 如何使那些将捕获数据包的其他脚本可以访问这些变量。

  3. 在 bash 脚本上下文中是否有更好的方法来实现相同的结果?

这是我关于 stackoverflow 的第一个问题,我很高兴收到有关我的下一个问题如何变得更好的反馈!

4

1 回答 1

0

在一般编程中,当需要存储动态值集合时,通常会创建一个数组变量。在 Bash 4 中,可以使用mapfile内置函数创建索引数组:

mapfile -t ifaces <<< "$(find /sys/class/net -mindepth 1 -printf '%f\n')"

在此示例中,通过从此处的字符串中读取行来mapfile创建索引数组。这里字符串的内容是使用命令替换构建的。使用选项删除尾随换行符。ifaces-t

注意-mindepth 1选项的使用。该选项不包括/sys/class/net目录本身。

basename该命令不是调用,而是使用带有格式说明符的-printf操作(根据find) :%f

%f 删除了所有前导目录的文件名(仅最后一个元素)。

ifaces变量将在当前范围内可用。可以按如下方式遍历数组:

for i in "${ifaces[@]}"
do
  printf "%s\n" "$i"
done

注意,mapfile在 Bash 版本 4 中引入。

进程替换

这里的字符串可以替换为进程替换

mapfile -t ifaces < <(find /sys/class/net -mindepth 1 -printf '%f\n')

这只是一个偏好问题。

在管道中使用mapfile

可以在管道中使用mapfile,但数组的值将仅在管道命令的范围内可用。例如,以下脚本打印零:

find /sys/class/net -mindepth 1 -printf '%f\n' | mapfile -t ifaces
printf "%d" "${#ifaces[@]}"

为了ifaces在管道上下文中使用变量,请使用分组命令,例如:

find /sys/class/net -mindepth 1 -printf '%f\n' | {
  mapfile -t ifaces
  printf "%d" "${#ifaces[@]}"
}

显然,在这种情况下,ifaces变量的范围将被限制在组内。

使用函数

有多种方法可以从函数返回值。最简单的方法是设置或修改全局变量:

get_ifaces() {
  mapfile -t ifaces < <(find /sys/class/net -mindepth 1 -printf '%f\n')
}

但这是一种不好的做法,因为可能会无意中覆盖现有变量。

另一种方法是编写一个接受变量名的函数:

get_ifaces() {
  local var_name=$1
  local __ifaces

  mapfile -t __ifaces < <(find /sys/class/net -mindepth 1 -printf '%f\n')

  eval $var_name=\( "${__ifaces[@]}" \)
}

get_ifaces ifaces

啊,我必须写这个,就像我eval在示例中一样:警告,警告,警告!您应该尽可能避免使用eval,因为它可能会评估超出预期的值,例如,请参阅此讨论。但在这个特定的例子中,我没有看到使用eval.

于 2016-11-28T06:49:59.837 回答