IP
特定のアドレスを取得するための特定のスクリプトがありますMAC
。これに使用され、arp
うまく動作します。crontab
問題は、スクリプトを実行するプログラムを書くときに発生します。正しく機能して実行されますが、arp
コマンドを実行する行が機能しないため、スクリプトが実行されている場合にのみ正しく完了しますcrontab
。
スクリプトは次のとおりです。
#!/bin/bash
subred=192.168.1.0/24
mac=aa:bb:cc:dd:ff:gg
log() {...}
log info "Init program"
ip=$(nmap -sP $subred >/dev/null && arp -an | grep $mac | awk '{print $2}' | sed 's/[()]//g')
if [ $ip ]; then
log ok "IP found in $ip"
else
log error "IP not found"
fi
log info "Finished program"
crontab
スクリプトは毎時間実行するように設定されています@hourly /root/machaunter.sh
。タイミングがcron
よく合い、スクリプトがスムーズに実行され、権限やスクリプトの問題を排除しました。その証拠は生成されたログファイルです。
29/04/2020 14:00:01 Init program
29/04/2020 14:00:06 IP not found
29/04/2020 14:45:59 Init program
29/04/2020 14:46:08 IP found in 192.168.1.173
29/04/2020 14:46:09 Finished program
29/04/2020 15:00:01 Init program
29/04/2020 15:00:10 IP not found
29/04/2020 16:00:01 Init program
29/04/2020 16:00:13 IP not found
29/04/2020 17:00:01 Init program
29/04/2020 17:00:07 IP not found
29/04/2020 18:00:01 Init program
29/04/2020 18:00:05 IP not found
29/04/2020 18:25:43 Init program
29/04/2020 18:25:50 IP found in 192.168.1.173
29/04/2020 18:25:51 Finished program
ご覧のとおり、毎時間スクリプトを手動で2回実行すると正常に動作しますが、残りの時間にはそうではありません。
呼び出し時にarp
何も表示されないことが見つかるまでデバッグを続け、スクリプトテストに追加しましたが、手動で起動したときに表示されました(テスト用にログを追加し、毎分1log error "arp: $(arp -an)"
回実行するようにcrontabを変更しました* * * * /root/machaunter.sh
)。
30/04/2020 09:22:01 Init program
30/04/2020 09:22:01 arp:
30/04/2020 09:23:01 Init program
30/04/2020 09:23:01 arp:
30/04/2020 09:24:02 Init program
30/04/2020 09:24:02 arp:
30/04/2020 09:24:29 Init program
30/04/2020 09:24:29 arp: Address HWtype HWaddress Flags Mask Iface 192.168.1.46 ether 7e:2d:d1:ca:d9:c0 C br0 192.168.1.68 ether c894:66:dd:1c:c2:9d C br0 192.168.1.173 ether 48:48:59:e5:b8:5e C br0 192.168.1.1 ether bf:f1:54:4d:e3:25 C br0
30/04/2020 09:25:01 Init program
30/04/2020 09:25:01 arp:
30/04/2020 09:26:01 Init program
30/04/2020 09:26:01 arp:
30/04/2020 09:27:01 Init program
30/04/2020 09:27:01 arp:
30/04/2020 09:28:01 Init program
30/04/2020 09:28:01 arp:
30/04/2020 09:29:02 Init program
30/04/2020 09:29:02 arp:
30/04/2020 09:30:01 Init program
30/04/2020 09:30:01 arp:
30/04/2020 09:31:01 Init program
30/04/2020 09:31:01 arp:
ログに示すように、arp
コマンドは手動で起動した場合を除いてデータを返しません。ご覧のとおり、このコマンドが呼び出されるとスクリプトは終了しません(ログはありませんFinished program
)。
なぜこれが起こるのですか?解決策は何ですか?
CRONデーモンログアップデートの使用
● cron.service - Regular background program processing daemon
Loaded: loaded (/lib/systemd/system/cron.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2020-04-27 18:09:19 UTC; 2 days ago
Docs: man:cron(8)
Main PID: 486 (cron)
CGroup: /system.slice/cron.service
└─486 /usr/sbin/cron -f
Apr 30 10:40:01 NanoPi-R1 CRON[14428]: (root) CMD (/root/machaunter.sh)
Apr 30 10:40:01 NanoPi-R1 CRON[14429]: (root) CMD ( /bin/bash /usr/bin/sync_ntp_rtc.sh /dev/rtc0)
Apr 30 10:40:01 NanoPi-R1 CRON[14421]: (CRON) info (No MTA installed, discarding output)
Apr 30 10:40:01 NanoPi-R1 CRON[14421]: pam_unix(cron:session): session closed for user root
Apr 30 10:40:04 NanoPi-R1 CRON[14420]: (CRON) info (No MTA installed, discarding output)
Apr 30 10:40:04 NanoPi-R1 CRON[14420]: pam_unix(cron:session): session closed for user root
Apr 30 10:41:01 NanoPi-R1 CRON[14459]: pam_unix(cron:session): session opened for user root by (uid=0)
Apr 30 10:41:01 NanoPi-R1 CRON[14463]: (root) CMD (/root/machaunter.sh)
Apr 30 10:41:01 NanoPi-R1 CRON[14459]: (CRON) info (No MTA installed, discarding output)
Apr 30 10:41:01 NanoPi-R1 CRON[14459]: pam_unix(cron:session): session closed for user root
stdoutコマンドを使用した更新
crontabコマンドにXXXXリダイレクトを追加しました>/tmp/logfile 2>&1
。
* * * * * /root/machaunter.sh >/tmp/logfile 2>&1
/tmp/logfile
私が得た後:
30/04/2020 13:52:01 [info] Init program
/root/machaunter.sh: line 37: arp: command not found
30/04/2020 13:52:01 [info] arp:
答え1
PATH
cron このスクリプトを実行する環境は、一般的な対話型環境と比較して変数値が異なります。
これは、スクリプトがarp
コマンドを探す場所がわからないことを意味します。たとえば(コメントで述べたように)。
command -v
対話型シェルで各ツールを実行して、スクリプトで使用されているツールのディレクトリをメモしておくことをお勧めします。
command -v nmap
command -v arp
など。
これにより、そのコマンドのパス名のリストが表示されます。これらのディレクトリ名を取得し、PATH
スクリプト自体(スクリプトの先頭)に追加します。
PATH=$PATH:/some/directory/path:/another/directory/path
スクリプトでこれを行うと、スクリプトはツールを見つけることができます。
最後に、以下を追加するだけです/usr/sbin
。
PATH=$PATH:/usr/sbin
別のオプションは、ツールと絶対パスを使用することです(/usr/sbin/arp
例:arp
。
答え2
arp
でスクリプトを実行するには、代わりにasパスをcrontab
使用する必要があります。なぜなら、スクリプトの実行はデフォルトでwhileにあるからです。arp
/sbin/arp
arp
crontab
/bin
arp
/sbin/