OS ディストリビューションに応じて OS バージョンと利用可能なセキュリティ パッチの数をチェックする bash スクリプトを作成しました。
ここでの質問は、スクリプトが Ubuntu OS では動作しないということです。スクリプトは以下のとおりです。
#!/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
Ubuntu マシンの O/p:
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
上記の Ubuntu システムでは、スクリプトが期待どおりに動作しません。つまり、OS バージョンとセキュリティ パッチの数を出力する必要があります。
答え1
主な問題が 2 つあります。まず、スクリプトを ではsh
なく で実行していますが、ではサポートされていないbash
bash 機能 ( 構造) を使用しています。したがって、 が実行可能である場合は、 または を実行する必要があります。[[
sh
bash getos.sh
./getos.sh
次に、コマンドを好きな場所で中断することはできません。制御演算子. したがって、これは失敗します:
SECPKGCOUNT=$(sudo apt list --upgradable 2>/dev/null | grep "\-security"
| wc -l)
これは機能しますが:
SECPKGCOUNT=$(sudo apt list --upgradable 2>/dev/null | grep "\-security" |
wc -l)
次に、いくつかの小さな問題があります。最初の は、存在するif ... elif .. else
場合/etc/os-release
、残りは決して実行されないことを意味します。したがって、 とOS
の両方REDHAT
が設定されている状況は決して発生しません。ただし、両方を期待しているようですが、Red Hat システムから が欠落する理由は見当たりません。したがって、ではなく/etc/os-release
、別の が必要だと思います。if
if ... elif
最後に、コマンドの一部 (awk
とgrep | wc
) を簡略化できます。実際には必要のない変数を作成していますが、次のようにすると全体を少し簡単にすることができます。
#!/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"