将重复的代码转换成循环

时间:2018-07-20 18:46:18

标签: shell sh wake-on-lan dd-wrt

我有一个运行DD-WRT的路由器,该路由器具有用于在某些端口上的LAN请求上唤醒计算机的启动脚本。我找到了这个shell脚本here,并对其进行了更改,以允许在多个端口上唤醒。我试着做一个for循环,这样我就不必重复任何代码,但这是行不通的。唯一起作用的是:

#!/bin/sh
#Enable JFFS2 and place script in /jffs/ then run on startup in web interface.
#You can check the log from http://192.168.1.1/user/wol.html
INTERVAL=1
PINGTIME=1
OLD=""
PORTPLEX=32400
PORTFTPCTRL=20
PORTFTPDATA=21
PORTRDP=3389
WOLPORT=9
TARGET=192.168.1.8
BROADCAST=192.168.1.255
MAC=aa:bb:cc:dd:ee:ff
WOL=/usr/sbin/wol
LOGFILE="/tmp/www/wol.html"
echo "<meta http-equiv=\"refresh\" content=\"10\">" > $LOGFILE
echo "["`date`"] AUTO WOL Script started. <br>" >> $LOGFILE

while sleep $INTERVAL;do

NEW=`dmesg | awk '/ACCEPT/ && /DST='"$TARGET"'/ && /DPT='"$PORTPLEX"'/ {print }' | tail -1`
SRC=`dmesg | awk -F'[=| ]' '/ACCEPT/ && /DST='"$TARGET"'/ && /DPT='"$PORTPLEX"'/ {print $7}' | tail -1`
LINE=`dmesg | awk '/ACCEPT/ && /DST='"$TARGET"'/ && /DPT='"$PORTPLEX"'/'`
if [ "$NEW" != "" -a "$NEW" != "$OLD" ]; then
   if ping -qw $PINGTIME $TARGET >/dev/null; then
      echo "NOWAKE $TARGET was accessed by $SRC and is already alive at" `date` "<br>">> $LOGFILE
   else
      echo "WAKE $SRC causes wake on lan at" `date` "<br>">> $LOGFILE
      $WOL -i $BROADCAST -p $WOLPORT $MAC >> $LOGFILE
      echo "<br>" >> $LOGFILE
      sleep 1
   fi
   OLD=$NEW
fi

NEW=`dmesg | awk '/ACCEPT/ && /DST='"$TARGET"'/ && /DPT='"$PORTFTPCTRL"'/ {print }' | tail -1`
SRC=`dmesg | awk -F'[=| ]' '/ACCEPT/ && /DST='"$TARGET"'/ && /DPT='"$PORTFTPCTRL"'/ {print $7}' | tail -1`
LINE=`dmesg | awk '/ACCEPT/ && /DST='"$TARGET"'/ && /DPT='"$PORTFTPCTRL"'/'`
if [ "$NEW" != "" -a "$NEW" != "$OLD" ]; then
   if ping -qw $PINGTIME $TARGET >/dev/null; then
      echo "NOWAKE $TARGET was accessed by $SRC and is already alive at" `date` "<br>">> $LOGFILE
   else
      echo "WAKE $SRC causes wake on lan at" `date` "<br>">> $LOGFILE
      $WOL -i $BROADCAST -p $WOLPORT $MAC >> $LOGFILE
      echo "<br>" >> $LOGFILE
      sleep 1
   fi
   OLD=$NEW
fi

NEW=`dmesg | awk '/ACCEPT/ && /DST='"$TARGET"'/ && /DPT='"$PORTFTPDATA"'/ {print }' | tail -1`
SRC=`dmesg | awk -F'[=| ]' '/ACCEPT/ && /DST='"$TARGET"'/ && /DPT='"$PORTFTPDATA"'/ {print $7}' | tail -1`
LINE=`dmesg | awk '/ACCEPT/ && /DST='"$TARGET"'/ && /DPT='"$PORTFTPDATA"'/'`
if [ "$NEW" != "" -a "$NEW" != "$OLD" ]; then
   if ping -qw $PINGTIME $TARGET >/dev/null; then
      echo "NOWAKE $TARGET was accessed by $SRC and is already alive at" `date` "<br>">> $LOGFILE
   else
      echo "WAKE $SRC causes wake on lan at" `date` "<br>">> $LOGFILE
      $WOL -i $BROADCAST -p $WOLPORT $MAC >> $LOGFILE
      echo "<br>" >> $LOGFILE
      sleep 1
   fi
   OLD=$NEW
fi

NEW=`dmesg | awk '/ACCEPT/ && /DST='"$TARGET"'/ && /DPT='"$PORTRDP"'/ {print }' | tail -1`
SRC=`dmesg | awk -F'[=| ]' '/ACCEPT/ && /DST='"$TARGET"'/ && /DPT='"$PORTRDP"'/ {print $7}' | tail -1`
LINE=`dmesg | awk '/ACCEPT/ && /DST='"$TARGET"'/ && /DPT='"$PORTRDP"'/'`
if [ "$NEW" != "" -a "$NEW" != "$OLD" ]; then
   if ping -qw $PINGTIME $TARGET >/dev/null; then
      echo "NOWAKE $TARGET was accessed by $SRC and is already alive at" `date` "<br>">> $LOGFILE
   else
      echo "WAKE $SRC causes wake on lan at" `date` "<br>">> $LOGFILE
      $WOL -i $BROADCAST -p $WOLPORT $MAC >> $LOGFILE
      echo "<br>" >> $LOGFILE
      sleep 1
   fi
   OLD=$NEW
fi

done

我猜测是(1)我不太了解bash中的for循环是如何工作的,或者(2)DD-WRT的shell脚本与其他版本的Linux不同,或者两者都有。

我将如何转换这部分代码以在遍历每个端口的for循环中执行?

NEW=`dmesg | awk '/ACCEPT/ && /DST='"$TARGET"'/ && /DPT='"$PORT"'/ {print }' | tail -1`
SRC=`dmesg | awk -F'[=| ]' '/ACCEPT/ && /DST='"$TARGET"'/ && /DPT='"$PORT"'/ {print $7}' | tail -1`
LINE=`dmesg | awk '/ACCEPT/ && /DST='"$TARGET"'/ && /DPT='"$PORT"'/'`
if [ "$NEW" != "" -a "$NEW" != "$OLD" ]; then
   if ping -qw $PINGTIME $TARGET >/dev/null; then
      echo "NOWAKE $TARGET was accessed by $SRC and is already alive at" `date` "<br>">> $LOGFILE
   else
      echo "WAKE $SRC causes wake on lan at" `date` "<br>">> $LOGFILE
      $WOL -i $BROADCAST -p $WOLPORT $MAC >> $LOGFILE
      echo "<br>" >> $LOGFILE
      sleep 1
   fi
   OLD=$NEW
fi

谢谢!

1 个答案:

答案 0 :(得分:0)

您尝试过吗? :

for PORT in $PORTPLEX $PORTFTPCTRL $PORTFTPDATA $PORTRDP; do
            NEW=`dmesg | awk '/ACCEPT/ && /DST='"$TARGET"'/ && /DPT='"$PORT"'/ {print }' | tail -1`
    SRC=`dmesg | awk -F'[=| ]' '/ACCEPT/ && /DST='"$TARGET"'/ && /DPT='"$PORT"'/ {print $7}' | tail -1`
    LINE=`dmesg | awk '/ACCEPT/ && /DST='"$TARGET"'/ && /DPT='"$PORT"'/'`
    if [ "$NEW" != "" -a "$NEW" != "$OLD" ]; then
       if ping -qw $PINGTIME $TARGET >/dev/null; then
          echo "NOWAKE $TARGET was accessed by $SRC and is already alive at" `date` "<br>">> $LOGFILE
       else
          echo "WAKE $SRC causes wake on lan at" `date` "<br>">> $LOGFILE
          $WOL -i $BROADCAST -p $WOLPORT $MAC >> $LOGFILE
          echo "<br>" >> $LOGFILE
          sleep 1
       fi
       OLD=$NEW
    fi
done