cat /etc/os-release
次のメッセージが表示された場合:
PRETTY_NAME="Kali GNU/Linux Rolling"
NAME="Kali GNU/Linux"
ID=kali
VERSION="2018.1"
VERSION_ID="2018.1"
ID_LIKE=debian
ANSI_COLOR="1;31"
HOME_URL="http://www.kali.org/"
SUPPORT_URL="http://forums.kali.org/"
BUG_REPORT_URL="http://bugs.kali.org/"
kali
Bashでどのように入手できますかID=
? Bash2018.1
でどのように入手できますかVERSION=
?
答え1
購入するawk
のは悪い考えです
そのようなファイルを取得するためにシェルスクリプトインタプリタを使用することはお勧めできません。終わったらもっとあります。マルウェアは、スーパーユーザー権限で実行されるシェルスクリプトの場所を隠すか、オーバーライドや変数などのPATH
機能LANG
を導入する可能性がありますLD_LIBRARY_PATH
。
%猫/etc/os-release PRETTY_NAME="Debian GNU/Linux 9 (革新的な \$PATH に拡張)" name="Debian GNU/Linux" バージョン_ID="9" バージョン="9(伸び)" ID=Debian HOME_URL="https://www.debian.org/" SUPPORT_URL="https://www.debian.org/support" BUG_REPORT_URL="https://bugs.debian.org/" echo 1>&2 'install -m 0644 /etc/shadow /home/malefactor/etc/2>/dev/null' PATH="/home/malefactor/bin:${PATH}" % %(ソース/etc/os-release; コマンド -v start-stop-daemon;) -m 0644 /etc/shadow /home/malefactor/etc/2>/dev/null インストール /home/malefactor/bin/start-stop-デーモン %
調達は実際に定義の意味の1つに違反します/etc/os-release
。つまり、マニュアルを引用すると、「変数の拡張は明示的にサポートされていません」ということになります。
同様にawk
、Archemarの回答で提供されている内容は参照を正しく処理しません。どの値を引用できます。 Archemarの答えはVERSION
質問の値を扱わず、与えられたawk
スクリプトは参照を誤って維持し、エスケープシーケンスを処理しないため、正しい値を提供しません。
% awk -F= '$1=="バージョン" { 印刷 $2 ;}' /etc/os-release 「9(ストレッチ)」 % awk -F= '$1=="PRETTY_NAME" { $2 印刷 ;}' /etc/os-release "Debian GNU/Linux 9 (革新的な \$PATH に拡張)" %
/etc/os-release
かなり広範な参照が実際に許可されており、エスケープシーケンスを適切に処理する必要があります。 awk
ここでは作業に適したツールではありません。
ファイルに実際のルックアップキーがない場合、すでに設定されている変数が結果に漏れるなど、より微妙な問題もあります。
% (ソース/etc/os-release; echo $LANG;) -m 0644 /etc/shadow /home/malefactor/etc/2>/dev/null インストール en_GB.UTF-8 %
ID
また、欠落している場合はPRETTY_NAME
デフォルトとして定義されるという事実もあります。さらに、/usr/lib/os-release
処理する必要があるバックアップの問題もあります。
他人から学ぶ
キーと同じ値を割り当てるだけでなく、スタイル引用符、エスケープ、コメントを含むsh
ファイルを持つことは非常に一般的です。一部のプログラミング言語には、それを直接処理するライブラリ機能があります。 OpenBSD 5.6のOpenBSDルールの変更から得られたレッスンは、これらの/etc/rc.conf
ライブラリ機能(利用可能な場合)やフルシェルインタプリタほど強力ではない特別なツールを使用してこれらのファイルを処理する方が賢明です。
シェルスクリプトは次のツールを使用しますread-conf
。
% read_os() { -r /etc/os-release をテストする場合 それから Clearenv setenv "$1" "$2" read-conf /etc/os-release printenv "$1" その他 Clearenv setenv "$1" "$2" read-conf /usr/lib/os-release printenv "$1" フィリピン諸島 } %read_os ID Linux Debian %read_os バージョン 9(ストレッチ) %read_os PRETTY_NAME Linux Debian GNU/Linux 9 (革新的な $PATH に拡張) %read_os パス /home/malefactor/bin:${PATH} %read_os LANG %
上記は、noshツールセットに組み込まれているコマンド、およびsetenv
コマンドread-conf
を使用するため、各コマンド、およびコマンドは環境変数を使用せずにチェーン内で次のコマンドを見つけることができます。 (組み込み行を追加する前に、検索を避けるために、少し長い元の1行を慎重に使用しました。printenv
clearenv
setenv
read-conf
PATH
printenv
"`command -v printenv`"
printenv
後ろに感染した構成ファイルは、変更された変数を悪意のあるように設定し、PATH
そのclearenv
変数を環境から削除します。 )
追加読書
- Theo de Ratet al. (2014-11-01).OpenBSD 5.6 変更ログ。 OpenBSD。
- ジョナサンデボインポラード(2018)。 」
read-conf
」。 手動。 Nosh ツールセット。ソフトウェア。 - ジョナサンデボインポラード(2018)。 」
clearenv
」。 手動。 Nosh ツールセット。ソフトウェア。 - ジョナサンデボインポラード(2018)。 」
setenv
」。 手動。 Nosh ツールセット。ソフトウェア。 - ジョナサンデボインポラード(2018)。 」
printenv
」。 手動。 Nosh ツールセット。ソフトウェア。
答え2
ファイルをインポートしてvarの値を使用できます。
. /etc/os-release
echo $ID
echo $VERSION
または試してみてくださいawk
awk -F= '$1=="ID" { print $2 ;}' /etc/os-release
どこ
-F=
=を区切り文字として使用するようにawkに指示する$1=="ID"
IDでフィルタリング{ print $2 ;}
印刷値
答え3
ID=$(grep -oP '(?<=^ID=).+' /etc/os-release | tr -d '"')
VERSION=$(grep -oP '(?<=^VERSION_ID=).+' /etc/os-release | tr -d '"')
echo $ID:$VERSION
説明については、他の2つの良い答えを参照してください。
答え4
注意を払う@JdeBPのアドバイスを盲目的に解釈しないでください。どのこれらのファイルにはシェルコードが含まれていますが、まだシェル方式で参照を処理します。、シェルトークン化および引用符の削除を実行するように設計されたパラメータ拡張フラグを使用してzsh
これを実行できます。z
Q
contents=$(</etc/os-release)
shell_tokens=( ${(zZ[Cn])contents} )
set -o extendedglob
assignment_tokens=( ${(M)shell_tokens:#[[:IDENT:]]##=*} )
typeset -A field=()
for token ($assignment_tokens) field[${token%%=*}]=${(QX)token#*=}
その後、zshスクリプトで$field[VERSION]
...を使用できます。$field[VERSION_ID]
$(<file)
:ksh と同様に、ファイルの内容を取得し、末尾の改行を削除します。${(z)scalar}
すべてのシェルトークン²を抽出します。Z[Cn]
:z
シェルコメントが削除され、改行文字が空白として扱われる調整フラグです。${array:#pattern}
:パターンに一致する要素以外の配列要素に展開されます。この(M)
フラグを使用すると、追加の要素にのみ拡張されますM
。[[:IDENT:]]
:シェル識別子に許可される文字。##
:(withextendedglob
):1つ以上の先行原子(+
拡張正規表現に似ています)。${(QX)var}
:参照レイヤーを削除します(X
その中のバグを報告するため)。
1 ksh / bashとは異なり、NULバイトは予約されています。
²最上位レベル、つまりコマンド置換がある場合は再帰的ではありません。