ほぼすべてのスクリプトで使用する 7 つの Bash 変数
現在 Bash を学習していますか?次のようなものを見たことがありますか $0 そして $EUID それが何を意味するのか疑問に思いましたか?または違いは何ですか $UID そして $EUID?それらが何をするのか、なぜ重要なのかなどについて説明します。
特別なパラメータ
覚えておく価値のある素早いアクション
特殊パラメータは、特定の目的のために Bash によって提供される変数です。それらは 10 個未満ですが、次のものが最も便利だと思います。
スクリプトのパスを取得する
スクリプトを作成しているときに、そのパスを知りたい場合があります。たとえば、ヘルプ メニューを作成するときは、上部にスクリプトの名前を含めるのが一般的です。 ls コマンドのヘルプ メニューは次のとおりです。
ls --help
(相対) パスには、 $0 特別なパラメータ。これは POSIX 標準であるため、ほとんどのシェルで使用できます。
echo "$0"
次に、次を使用してスクリプト名を取得できます $(basename $0):
ただし、場合によっては、 $0 信頼性がありません – たとえば、ソース /path/to/script.sh スクリプトパスではなく「bash」を返します。その代わりに、 $BASH_SOURCE 変数は、驚くべき点がない限り、ほぼ同じように機能します。 Bash のみを使用する場合は、Bash がより良い選択ですが、他のシェルには移植できません。
プロセスの終了ステータスを確認する
すべてのプログラムは終了時に数値を返します。これは終了コードと呼ばれ、コマンドがエラーを返した場合の判断に使用されます。たとえば、次のようにしようとすると、 ls 存在しないディレクトリの場合は、ゼロ以外の値が返されます。
終了ステータスがゼロの場合は成功を意味します。ゼロ以外の場合は問題があることを示します。
問題が発生した場合は、実行を停止する必要があるかもしれません。 $? 特別なパラメータは必要な終了コードを提供します。
ls /system32
echo $?
終了コードを検出して処理するには、いくつかの方法があります。最も明白なのは、「$?」を評価することです。条件付きステートメント:
if (( $? -eq 0 )); then
# If the script executed successfully.
fi
通常、終了コードは何らかの意味を持ち、プログラム固有のものですが、case ステートメントを使用して個別の値を処理できます。
case $? in
0) echo "OK";;
1) echo "Err";;
*) echo "Unhandled error";;
esac
私のお気に入りのアプローチは、括弧なしで条件文を使用することです。
if ls /system32; then
# Upon zero exit code.
echo "/system32 exists"
fi
しかし、最も洗練された解決策は、論理演算子を使用することです。
ls /system32 && echo "/system32 exist" # && executes on zero exit status.
ls /system32 || echo "/system32 does not exist" # || executes on non-zero exit status.
引数にアクセスする
Bash スクリプトを作成している場合は、常に値 (引数または位置パラメータ) を渡す必要があります。 Bash のアプローチは少しぎこちないですが、機能します。それらを理解する最も簡単な方法は例です。
foo() このテーマについてさらに詳しく知りたい方は以下をご覧ください
foo "first" "second"
関数に引数を渡しましたが、それらはスクリプトのトップレベルではまったく同じように機能します。例えば:
#!/usr/bin/env bash
# This is the top-level of your script.
echo "The first argument: $1"
echo "The second argument: $2"
その後、CLI を介してスクリプトに引数を渡すことができます。 script.sh "first" "second"。
次に、「$@」特殊パラメータはすべての引数を配列として表します。
foo() 公式情報はこちら
foo "first" "second"
“$*” 特殊パラメーターは、すべての引数を 1 つの文字列に入れることを除いて、”$@” と同じです (“$*” に二重引用符が含まれている場合)。
at() このテーマについてさらに詳しく知りたい方は以下をご覧ください
star() 完全ガイドはこちら
at "one two" "three"
star "one two" "three"
「$@」は 2 つの引数を 2 行に分けて出力しますが、「$*」は 1 行に出力することがわかります。
引数の数を取得するには、 $関連情報は以下のリンクからご確認いただけます または $公式情報はこちら 構文:
foo() {
echo $このテーマについてさらに詳しく知りたい方は以下をご覧ください
echo $公式情報はこちら
}
foo "one" "two"
環境変数
スクリプトをロックダウンしないでください
環境変数は、シェルによって実行中のプログラムに提供される値です。例えば、 $HOME 現在のユーザーのホーム ディレクトリへのパスを提供します。
ユーザーIDを取得する
場合によっては、スクリプト内の現在のユーザー ID を知る必要があります。たとえば、最近私は次のソケットと対話していました。 /run/user/1000 ディレクトリ。 「1000」はユーザー ID です。堅牢なスクリプトが必要な場合は、この値をハードコーディングすべきではありません。スクリプトを実行する別のユーザーが異なるユーザー ID を持つ可能性があるためです。
これに対処するには、 $UID そして $EUID 変数。 「$UID」にはバイナリを実行するユーザーのIDが表示されます。 「$EUID」(実効ユーザーID)は、バイナリを実行するプロセスのユーザーIDです。通常、これらは互いに等しいですが、setuid バイナリの場合は異なる場合があります。たとえば、sudo で何かを実行する場合、フォークがさまざまな段階で進行するにつれて変化します。
ps --forest -eo cmd,euid,ruid | grep -C 1 '(s)udo'
バックグラウンドで「sudo sleep 600」を実行しています。上記のプロンプトには、sudo を実行しているプロセスのコマンド、EUID (「1」)、および UID (「2」) 列が表示されます。 EUID はすぐに「0」になりますが、UID は最後のフォークされたプロセス (root として「スリープ」実行) まで変更されないことがわかります。
このことから何が分かるでしょうか?まあ、どれを使っても特に問題はありません。 「$EUID」は有効な権限であるため、root 権限があるかどうかを確認するために使用すると言う人もいます。ただし、イメージから、最後の「スリープ」プロセスでは UID と EUID の両方が「0」(ルート) に設定されており、シェル プロセスでは両方とも「1000」(ユーザー) に設定されていることがわかります。これらは、フォーク プロセスのどちらかの端、つまり sudo リクエストを開始した場所と、最終的な実行プロセスを表します。したがって、重要な場合にはそれらの間に有用な区別はありませんが、フォーク プロセス中の setuid バイナリではそれらが異なることに注意してください。
共通ユーザーパスを取得する
私が作成するほぼすべてのスクリプトでは、ホーム ディレクトリにアクセスします。頻度は低いですが、アクセスする必要があります ~/.config または ~/.local/share。ファイル システム内の一般的な場所にアクセスするのは一般的ですが、このようにパスをハードコーディングすることは変更される可能性があるため、推奨されません。推奨されるアプローチは、freedesktop.org によって提供される標準変数のセットである XDG ディレクトリ仕様を使用することです。
env | grep XDG | sort -u
すべての変数が設定されているわけではなく、パスではない変数もあります。
XDG 変数を使用する場合は、常に適切なデフォルトを設定してください。
export "${XDG_CACHE_HOME:=$HOME/.cache}"
これにより、変数が設定され (未設定の場合)、実行するバイナリまたはスクリプトで使用できるようになります。
私が使用している最も一般的な変数は次のとおりです。
export "${XDG_CACHE_HOME:=$HOME/.cache}" # Semi-temporary data.
export "${XDG_CONFIG_HOME:=$HOME/.config}" # Configuration files.
export "${XDG_DATA_HOME:=$HOME/.local/share}" # Downloaded data, etc.
他にもいくつかあるので、ぜひ学習することをお勧めします。すべてを書き込むのではなく、これらの場所を使用する必要があります。 /tmp またはカスタムディレクトリ ~/。
変数を使用してスクリプトの機能性と移植性を維持する
これらの変数に加えて、多くの便利な環境変数がシェル経由で利用可能です。カバーされている変数は、私が最も頻繁に使用する変数を表しています。これらがなければ Bash スクリプトを書くことはできませんでした。逆に、値をハードコーディングすると、最終的に破損につながります。何百ものスクリプトがある場合、そのような破損はメンテナンスの悪夢になります。したがって、できる限り他の場所から、できれば標準変数から推測するのが最善であり、今日ここで紹介した変数はその要件に適合します。
最後に、できるだけ多くの標準変数を学習して使用してください。
{このテーマについてさらに詳しく知りたい方は以下をご覧ください|関連情報は以下のリンクからご確認いただけます}