Also, das Script hat aus meiner Sicht mehrere Probleme auf unterschiedlichen Ebenen.
Echt falsch ist z. B. die stderr-Redirection in dem Call zu
ping - der Benutzer dieses Scripts wird eine Datei Namens "%1" im CWD liegen haben. Gemeint ist wohl "2>&1", um stderr auf stdout zu kriegen. (Dieser etwas subtile Bug fuehrt auch dazu, dass das Script wohl immer noch nicht in allen denkbaren Faellen das macht, was der Autor wirklich von ihm haben moechte!)
Ein Stil-Problem, das aber zu einem echten werden kann, ist folgendes: `somecmd` (backticks) statt $(somecmd) zur command substitution zu verwenden ist generell eine schlechte Idee. $() ist besser lesbar, das Konstrukt laesst sich beliebig verschachteln, und Editoren tun sich leichter mit dem Hervorheben der Syntax. Es gibt KEINEN Grund, jemals irgendwo auf das aeltere `` zurueckzugreifen. In ungefaehr 101 von 100 Faellen ist es auszerdem Notwendig, das Expansionskonstrukt in double quotes zu packen, da man sonst von word splitting aufgeblattelt wird. Zusammengefasst als Handlungsempfehlung:
NIEMALS
`somecmd`.
QUASI NIEMALS
$(somecmd).
QUASI IMMER
"$(somecmd)".
Weiters: Konstrukte wie x="$(some command | grep some-string)" sind in den meisten Faellen irgendwo zwischen unnoetig und falsch. In diesem Fall hier geht es nur darum, sicherzustellen, dass "Unreachable" nicht im Output von `ping` vorkommt, was eine nicht ideale Methode ist, ping zu fragen, ob es erfolgreich hat arbeiten koennen. Das wird von allen gesunden Tools durch den exit status besser und eindeutig beantwortet.
Nachdem ein if-block durch eine if-list nach dem if eroeffnet wird, die von der Shell ausgefuehrt wird ([ und [[ sind Programme bzw. built-ins, die einen exit status zurueckgeben, der von if ausgewertet wird!), koennte man das so eleganter loesen:
if ping -c1 -w1 10.0.0.111 &>/dev/null
then
# code wenn Ziel erreichbar
else
# code wenn Ziel nicht erreichbar
fi
Wenn man mit einer Situation konfrontiert ist, wo der exit status nicht autoritativ aussagekraeftig ist, und man wirklich von grep gesagt bekommen moechte, dass irgendeine regex in seinem Input vorkommt, verwendet man idealerweise
grep -q ..., anstatt den Output in eine Shell-Variable zu packen. Das bringt grep dazu, durch seinen eigenen exit status zu sagen, ob der Ausdruck gefunden wurde (und zwar schon nach dem allerersten Match).
Weiters: Oft ist man, wie auch in diesem Fall, damit konfrontiert, mit der Shell einen "entfernten" (=nicht-Kind/Job-)Prozess zu beeinflussen. Das war in pre-systemd-Zeiten muehsam, aber seit
systemd-run es einem erlaubt, transient units zu starten (und zu stoppen), ist das viel sauberer moeglich. Als Beispiel:
colo@ryzealot[ssh:A]:~ $ systemd-run --user --unit myunit /bin/sleep 3600
Running as unit: myunit.service
colo@ryzealot[ssh:A]:~ $ systemctl status --user myunit
● myunit.service - /bin/sleep 3600
Loaded: loaded (/run/user/1000/systemd/transient/myunit.service; transient)
Transient: yes
Active: active (running) since Sun 2020-06-21 19:24:07 CEST; 26s ago
Main PID: 14666 (sleep)
CGroup: /user.slice/user-1000.slice/user@1000.service/myunit.service
└─14666 /bin/sleep 3600
Jun 21 19:24:07 ryzealot systemd[622]: Started /bin/sleep 3600.
colo@ryzealot[ssh:A]:~ $ systemctl stop --user myunit
colo@ryzealot[ssh:A]:~ $ systemctl status --user myunit
Unit myunit.service could not be found.
Ich hoffe das illustriert ausreichend gut, wie man sich den fehleranfaelligen
pkill-Tanz ersparen koennte.
Weiters: In Scripts, die via cron ausgefuehrt werden, tut man oft gut daran, PATH explizit zu setzen, sodass alle im Script verwendeten Tools auch sicher aufgerufen werden koennen.
Das ist erstmal alles, was mir zum geposteten Script einfaellt. Ich hoffe, es hilft einigen weiter