Gnu / Linuxとはどういう意味ですか?

Gnu / Linuxとはどういう意味ですか?

このコマンドを実行すると、Gnu / Linuxは実際に何をしていますか?

cd; ls /Bin/g* &> /dev/null; echo $?

最終出力はゼロです。

答え1

gその文字で始まる名前がディレクトリにあることを確認することが目的であれば、シェル/Binにはより良いアプローチがあります。bash

shopt -s nullglob
set -- /Bin/g*
if [ "$#" -ne 0 ]; then
    printf 'There are %d names starting with "g" in /Bin\n' "$#"
    echo 'These are those names:'
    printf '\t%s\n' "$@"
else
    echo 'No names in /Bin start with "g"'
fi

実行中のシステムにいると仮定するとbash...

0パターンと一致する名前があり、パターンと一致する名前がない場合、または一部のディレクトリ権限がそれを許可しない場合、コマンドセットはゼロ以外の/Bin/g*値(おそらく2ゼロではない可能性があります)を出力します。 ) を出力してリストを生成します。1ls

最初に始めることはcd興味深いものではなく、おそらく必要ではありません(このコマンドを削除すると影響を与える状況は非常に人為的です)。現在のディレクトリを任意の値に変更するか、設定されていない場合(または同等のデータベース)$HOME/etc/passwd定義されたホームディレクトリに変更します。HOME

コマンドを実行する前に、lsシェルは/Bin/g*パターンを一致する名前のリストに展開します。ディレクトリリストを読み取る権限があり、/Binディレクトリ/Binに文字で始まる名前があるg場合は、その名前リストがの引数であるパターンを置き換えますls。一致するものがない場合、または正しいアクセス権がない場合、/Binパターンはそのまま残ります。

実行すると、lsシェル拡張によって提供された引数のリストを取得し、その名前を/Bin/g*リストしようとします。これらの名前が存在し、あなたに何らかの名前をリストする権限があることを考慮すると、サブディレクトリ/Bin文字で始まるgコマンドはls最終的に正常に終了し、終了ステータスを返します0。名前がこの場合いいえ存在するか名前のいずれかがリストする権限を持たないサブディレクトリを参照すると、ゼロ以外の終了状態で失敗します(この場合はGNUから返されますls)。2

これは、シェル&>/dev/nullから標準出力と標準エラーストリームにリダイレクトするリダイレクトです。実行すると、これはコマンドのすべての出力とすべてのエラーが削除されることを意味します(記録された特殊なデバイスファイルです。すべてのデータが削除されます)。入るとき)。リダイレクト演算子は標準ではなく、「標準出力にリダイレクトしてから、標準エラーを標準出力がある場所にリダイレクトします」と書く方が良いでしょう。技術的には、このステップはシェルがワイルドカードパターンを拡張する前にも発生します。bash/dev/nullls/dev/null&>>/dev/null 2>&1/dev/null/Bin/g*

最後に、echo $?最新の終了ステータスを出力します。これは終了ステータスls(またはスキーマ拡張の失敗によって発生したエラーコード、または見つからないか、まったく実行され/Bin/g*なかったために発生したエラーコードである可能性がある、以下を参照)です。ls$PATH

これに影響する2つのシェルオプションがあります。

  1. このオプションが現在のシェルセッションで設定されている場合、nullglobモード/Bin/g*は次のようになります。完全に削除維持されるより。これはls引数なしで実行され、リストが表示されることを意味します。現在のディレクトリ(ホームディレクトリにすることができますcd)。現在のディレクトリを読み取る権限がある場合、これは成功します。ディレクトリの内容を読み取る権限がない場合は、ゼロ以外のls終了ステータスが返されます(この場合はGNUlsが返されます)。1

  2. シェルオプションが設定され、failglobパターンに一致する名前が/Bin/*ない場合シェル文句を言い、no match: /Bin/g*ゼロ以外の終了状態を取得します(おそらくまったく実行されません1)。ls

    エラーメッセージの生成はシェルで、シェルの標準エラーストリームは次のとおりです。いいえこのエラーメッセージは最終印刷の前に端末に印刷されます/dev/null(これはリダイレクトされた出力ストリームにすぎず、lsこの場合は実行されないことを覚えておいてください)。lsecho $?1

シェル変数は以下に影響します。

  • この変数は、シェルが引用符なしの値を拡張したときに適用されますIFS。これがecho $?最後のステップ( )で行うことです。シェルが$?正しい値で呼び出されるように拡張されると、最初にecho文字を区切り文字として使用して値を単語に分割します。$IFSデフォルトでは、$IFSこれはスペース、タブ、および改行です。

    IFS文字列に設定すると(012GNUを使用している場合は可能な値です)、シェルは値(の終了状態)を空の文字列に分割します(値が区切り文字として扱われるため)。引数なしで呼び出されると、出力として単一の改行文字が生成されます。$?bashls$?lsecho

    このような不幸な状況を回避するには、次のものを使用できますecho "$?"(二重引用符を参照$?)。

含まれていません:

  • PATHlsになければ何が起こり、起こらないのか、そしてこれがに$PATH影響しないのはなぜですか?cdecho
  • 実際にコマンドを実行することに関連するすべて、fork+execなど。
  • エイリアスは、ツールのシェル機能またはを拡張またはオーバーライドしますcdlsecho
  • シェル以外のbash場所では何が起こりますか、その理由は何ですか?
  • 効果set -f

関連情報