
条件と演算子を使用してLinuxオペレーティングシステムとバージョンを検出し、結果に応じて別のコマンドを実行するスクリプトを作成しようとしています。
オペレーティングシステムの検出
if [ -f /etc/os-release ]; then
. /etc/os-release
OS="$NAME"
OS_version="$VERSION_ID"
elif [ -f /etc/debian_version ]; then
# Older Debian/Ubuntu/etc.
OS="Debian"
OS_version="$(cat /etc/debian_version)"
fi
この変数をエコーすると返されます。
$ echo $OS
Debian GNU/Linux
$ echo $OS_version
10
以下の例では一致させたいと思います。ダーバンおよびオペレーティングシステムのバージョン10。しかし、$運営体制変数には単語以上の内容が含まれます。ダーバンしたがって、部分一致を実行するには一種のワイルドカードが必要です。
コマンドの置き換えで動作させる唯一の方法は、エコーすることです。$運営体制変数をstdoutに変換してgrepコマンドにパイプし、ワイルドカード検索を実行します。これは私が思いついたif文です。
if [ "$(echo "$OS" | grep 'Debian*')" -a "$OS_version" -ge 10 ]; then
echo "OS is Debian"
sleep 4
else
echo "OS is other"
sleep 4
fi
私はこのスクリプトを他のUnixベースのオペレーティングシステムで使用するので、このスクリプトをできるだけ広く互換性があり、POSIX標準に準拠したいと思います。
Ubuntu 21.04でスクリプトをテストしている間、Linuxでは、小数点以下の桁数が含まれている場合、どの数字が他の数字よりも大きいかを把握するのが難しいことがわかりました。以下では、2つの整数を小数点以下の2桁にエクスポートし、ifステートメントを使用して他の数より大きいか等しいかどうかを確認する2つのシェルスクリプトを作成しました。
20.10.sh
#!/bin/sh
export OS_version="20.10"
if [ "$OS_version" -ge 21.04 ]; then
echo "Your OS is new enough"
sleep 2
else
echo "Your OS is too old!"
sleep 2
fi
20.10.sh出力
~$ ./20.10.sh
YOUR OS VERSION IS >> 20.10
./20.10.sh: 6: [: Illegal number: 20.10
Your OS is too old!
23.45.sh
#!/bin/sh
export OS_version="23.45"
if [ "$OS_version" -ge 21.04 ]; then
echo "Your OS is new enough"
sleep 2
else
echo "Your OS is too old!"
sleep 2
fi
23.45.sh 出力
~$ ./23.45.sh
YOUR OS VERSION IS >> 23.45
./23.45.sh: 6: [: Illegal number: 23.45
Your OS is too old!
これ23.45.shスクリプトは「あなたのオペレーティングシステムが十分に新しくなっています」とエコーする必要がありますが、エコーせずに誤った数字のエラーを表示します。
小数点以下の桁数で他の数字のサイズを検出する方法はありますか?
答え1
標準[
コマンドは数値比較演算子で10進整数のみをサポートします。一部[
の実装([
組み込み実装など)はksh93
浮動小数点数と拡張をサポートしますが、これは移植性がなく、とにかく浮動小数点比較はバージョン比較と同じではありません。
たとえば、10.2
浮動小数点数はより大きいが、バージョンとして解釈されるとその10.10
逆になります。
Ubuntuのバージョンは日付です。 20.04(2020年4月)は20.10(2010年10月)以前です。これには、語彙比較を使用できます(willreach awk
10を使用して実行できます)。
1.2pre5-beta1.2
1.2
whileより小さいものは1.2a
通常より大きいと見なされます1.2
。バージョン命名規則がわからない場合は、バージョンを比較するのが難しいことがよくあります。
sort
GNUシステムでは、GNUのアルゴリズムに従うこともできます--version-sort
。
version_greater_than() {
local before_sort="$1"$'\n'"$2"
[ "$before_sort" != "$(printf %s "$before_sort" | sort --stable --version-sort)" ]
}
(ksh93 / zsh / bash構文)またはそれにsh
対応する構文:
version_greater_than() {
[ "$1
$2" != "$(printf '%s\n' "$1" "$2" | sort --stable --version-sort)" ]
}
その後、次のことができます。
if version_greater_than 10.10 10.4; then
echo 10.10 greater than 10.4
fi
awk
POSIXlyでは、任意の数値シーケンスを任意の長さでゼロで埋め、Cロケールで語彙比較を実行するアプローチをとることができます。
compare_versions() {
LC_ALL=C awk -- '
function pad(v, ret) {
while (match(v, /[0-9]+/)) {
ret = ret substr(v, 1, RSTART - 1) \
sprintf("%09d", substr(v, RSTART, RLENGTH))
v = substr(v, RSTART + RLENGTH)
}
return ret v
}
BEGIN {exit !(pad(ARGV[1]) '"$2"' pad(ARGV[2]))}' "$1" "$3"
}
次のように使用されます。
if compare_versions 1.10 '>' 1.2; then
echo '1.10 > 1.2'
fi
答え2
-lt
固定-ge
小数点または浮動小数点比較には、または同じ演算子を使用できません。これらは厳密な整数の数学演算子です。bash
(例)整数ではなく数学を実行する方法がわかりません。<
バージョン番号を文字列で比較するには、egまたはを使用する必要があります>=
。また、egが1.1
「より大きい」に注意する必要があります1.10
。sort -v
ロジックを構築することでこの問題を解決できます。
答え3
バージョン番号が浮動小数点(20.04.3と同じバージョンではない)の場合、比較をbc
。
たとえば、次のように変更します。
if [ "$OS_version" -ge 21.04 ]; then
これに関して:
if [ $(echo "$OS_version >= 21.04" | bc) ]; then