Ich habe ein Bash-Skript geschrieben, das die Betriebssystemversion überprüft und die Anzahl der verfügbaren Sicherheitspatches entsprechend der Betriebssystemverteilung zählt.
Die Abfrage hier ist, dass das Skript unter Ubuntu OS nicht funktioniert. Das Skript lautet wie folgt:
#!/bin/bash
# Detecting OS Distribution
if [ -f /etc/os-release ]; then
. /etc/os-release
OS=$PRETTY_NAME
elif [ -f /etc/redhat-release ]; then
REDHAT=$(cat /etc/redhat-release)
else
echo " OS is not supported "
fi
#Check how many packages for security and available to update
if [[ $OS == *"Red Hat"* ]] || [[ $OS == *"Amazon Linux"* ]] || [[ $OS ==
*"CentOS"* ]] || [[ $REDHAT == *"Red Hat"* ]] ; then
SECPKGCNT=$(sudo yum list-security --security | awk 'NR>2 {print last}
{last=$0}' | wc -l)
echo "${OS},${REDHAT},${SECPKGCNT}"
elif [[ $OS == *"Ubuntu"* ]] ;then
SECPKGCOUNT=$(sudo apt list --upgradable 2>/dev/null | grep "\-security"
| wc -l)
echo "${OS},${SECPKGCOUNT}"
else
echo " No security packages to update"
fi
O/p in Ubuntu-Maschine:
root@ip-XXXX:~# sh -x getos.sh
+ [ -f /etc/os-release ]
+ . /etc/os-release
+ NAME=Ubuntu
+ VERSION=14.04.5 LTS, Trusty Tahr
+ ID=ubuntu
+ ID_LIKE=debian
+ PRETTY_NAME=Ubuntu 14.04.5 LTS
+ VERSION_ID=14.04
+ HOME_URL=http://www.ubuntu.com/
+ SUPPORT_URL=http://help.ubuntu.com/
+ BUG_REPORT_URL=http://bugs.launchpad.net/ubuntu/
+ OS=Ubuntu 14.04.5 LTS
+ [[ Ubuntu 14.04.5 LTS = *Red Hat* ]]
getos.sh: 29: getos.sh: [[: not found
+ [[ Ubuntu 14.04.5 LTS = *Amazon Linux* ]]
getos.sh: 29: getos.sh: [[: not found
+ [[ Ubuntu 14.04.5 LTS = *CentOS* ]]
getos.sh: 29: getos.sh: [[: not found
+ [[ = *Red Hat* ]]
getos.sh: 29: getos.sh: [[: not found
+ [ Ubuntu 14.04.5 LTS = *Ubuntu* ]
getos.sh: 34: [: Ubuntu: unexpected operator
+ echo No security packages to update
No security packages to update
Im oben genannten Ubuntu-System funktioniert das Skript nicht wie erwartet. Ich meine, es sollte die Betriebssystemversion und die Anzahl der Sicherheitspatches drucken.
Antwort1
Sie haben zwei Hauptprobleme. Erstens führen Sie das Skript mit aus sh
, nicht bash
aber verwenden Bash-Funktionen (das [[
Konstrukt), die von nicht unterstützt werden sh
. Sie müssen also bash getos.sh
oder ausführen, nur ./getos.sh
wenn es ausführbar ist.
Als nächstes können Sie Befehle nicht an beliebiger Stelle unterbrechen, sondern müssen an einerKontrolloperator. Das hier wird also fehlschlagen:
SECPKGCOUNT=$(sudo apt list --upgradable 2>/dev/null | grep "\-security"
| wc -l)
Das würde zwar funktionieren:
SECPKGCOUNT=$(sudo apt list --upgradable 2>/dev/null | grep "\-security" |
wc -l)
Dann ein paar kleinere Probleme. Ihr erstes if ... elif .. else
bedeutet, dass /etc/os-release
Sie, wenn vorhanden, den Rest nie tun werden. Sie können also nie eine Situation haben, in der sowohl OS
als auch REDHAT
festgelegt sind. Sie scheinen jedoch beides zu erwarten, und ich sehe keinen Grund, warum dies /etc/os-release
in einem Red Hat-System fehlen sollte. Ich denke also, Sie möchten wahrscheinlich „separat“ if
anstelle von if ... elif
.
Schließlich können einige Ihrer Befehle (die awk
und die grep | wc
) vereinfacht werden. Sie erstellen Variablen, die eigentlich nicht benötigt werden, und das Ganze kann mit folgendem etwas einfacher gemacht werden:
#!/bin/bash
if [ -f /etc/os-release ]; then
. /etc/os-release
fi
if [ -f /etc/redhat-release ]; then
REDHAT=$(cat /etc/redhat-release)
fi
if [[ $PRETTY_NAME == *"Red Hat"* ]] || [[ $PRETTY_NAME == *"Amazon Linux"* ]] ||
[[ $PRETTY_NAME == *"CentPRETTY_NAME"* ]] || [[ $REDHAT == *"Red Hat"* ]]; then
SECPKGCNT=$(sudo yum list-security --security | awk 'NR>2 {k++}END{print k}')
PRETTY_NAME="$PRETTY_NAME,$REDHAT";
elif [[ "$PRETTY_NAME" == *"Ubuntu"* ]] ;then
SECPKGCNT=$(sudo apt list --upgradable 2>/dev/null | grep -c "\-security")
else
echo " OS is not supported "
exit
fi
echo "$PRETTY_NAME,$SECPKGCNT"