環境変数と位置パラメータ

環境変数と位置パラメータ

シェルには$0、、$1などの変数があります$2$?

以下を使用してシェルと環境変数を印刷してみました。

set

ただし、これらの変数はリストにありません。

したがって、デフォルトでは、これらの変数はシェル/環境変数とは見なされません。そうですか? (出力するときも$シェル/環境変数と同様に前に追加する必要があります)

答え1

変数は、シェルにある3つのタイプのパラメータのうちの1つです。

  1. 変える_名前が文字またはで始まり、その後にゼロ個以上の文字、数字、または後続する_有効なシェル識別子であるパラメーター。
  2. これ場所のパラメータは番号付きのパラメータです$1、、、$2...
  3. これ特別な$0パラメータは、さまざまな句読点を除いてすべて単一の文字名です。

setシェル変数のみが表示されます。

シェル変数のサブセットは環境変数であり、その値はシェルの起動時に環境から継承されるか、export有効名の属性を設定することによって生成されます。

答え2

環境変数と位置パラメータ

変数タイプについて説明する前に、$INTEGER変数タイプが正確に何であるか、環境変数とどのように異なるかを理解する必要があります。たとえば、変数を$INTEGER位置パラメータと呼びます。これはPOSIX(Portable Operating System Interface)規格で説明されています。セクション2.1(強調):

  1. シェルは関数(関数定義コマンドを参照)、組み込み関数(特殊組み込みユーティリティを参照)、実行可能ファイル、またはスクリプトを実行します。パラメーター名を1からnまでの位置引数として指定し、コマンド名(またはスクリプト内の関数の場合はスクリプト名)を位置引数番号0として指定します。(コマンドの検索と実行を参照)

$HOME対照的に、などの変数$PATHは環境変数です。対応する定義については後述する。標準第8条:

この章で定義されている環境変数は、さまざまなユーティリティ、機能、およびアプリケーションの動作に影響します。特定のユーティリティにのみ興味がある他の環境変数があります。単一ユーティリティにのみ適用される環境変数は、ユーティリティ記述の一部として定義されます。

説明に注意してください。位置引数はコマンドの前に表示する必要があります(例:)command positional_arg_1 positional_arg_2...。コマンドに何をすべきかを正確に伝えるためにユーザーが提供します。これにより、文字列がecho 'Hello' 'World'印刷されます。これは、作業したい項目の位置パラメータであるためです。位置引数を印刷する文字列として理解するように構築されています(などのオプションのフラグの1つではない場合)。別のコマンドでこれを行うと、数字が予想される可能性があるため、何と何がわかりません。位置パラメータは「継承」されません。つまり、子プロセスに明示的に渡されない限り、子プロセスは親プロセスの位置パラメータを知ることができません。多くの場合、ラッパースクリプトを使用して渡された位置引数を表示できます。これらのスクリプトは、コマンドの既存のインスタンスを確認したり、呼び出される実際のコマンドに追加の場所引数を追加したりできます。HelloWorldechoechoecho-nHelloWorld

対照的に、環境変数は複数のプログラムに影響を与えるように設計されています。彼ら環境変数はプログラム自体の外部で設定されるためです(詳細は以下を参照)。一部の環境変数(たとえば、HOMEまたは)PATHは特定の形式、特定の意味を持ち、すべてのプログラムで同じ意味を持ちます。変数は外部ユーティリティまたはシェル(およびスクリプト)に対して同じ意味を持ちます。つまり、HOMEプロセスが実行されているときのユーザー名のホームディレクトリです。/usr/bin/find環境変数は、特定のコマンドの動作を記述するために使用できます。例えば、UID環境変数は、スクリプトが root 権限で実行され、それに応じて特定のタスクに分岐することを確認するために使用できます。環境変数は継承可能です。子プロセスは親プロセス環境のコピーを取得します。また、見ることができますプロセスが親プロセスの環境を継承する場合、それをエクスポートする必要があるのはなぜですか。

簡単に言うと、環境変数はコマンドの外部で設定され、通常は変更されませんが、位置パラメータはコマンドによって処理され変更されます。


単純なシェルの概念

私はあなたがターミナルとシェルを混同したという意見を見たので、必ず読んでお勧めします。実端末昔は物理的なデバイスでした。今日、私たちが通常「ターミナル」と呼ぶ黒い背景と緑色のテキストを持つウィンドウは、実際にはソフトウェア、つまりプロセスです。ターミナルはシェルを実行するプログラムであり、シェルもプログラムですが、実行するために入力した内容を読み取ります(つまり、対話型シェルの場合、非対話型シェルはスクリプトと呼び出しの種類sh -c 'echo foo'です)。貝についてここ

これは重要な違いですが、端末がプログラムなので、同じ環境と場所の引数規則に従うことを認識することも重要です。起動時に環境変数をgnome-terminal調べて、SHELL使用しない限り、適切なデフォルトシェルを作成します-e。デフォルトのシェルを代わりにksh gnome-terminalに変更すると仮定すると、プログラムが環境をどのように使用できるかについての例でもあります。特定のシェルを実行するように明示的に指示すると、これは実行されますが永続的ではありません。対照的に、環境は本質的に変わりません(後で詳しく説明します)。kshbashgnome-terminal-e

ご覧のとおり、環境変数と位置変数はどちらも、シェルだけでなくプロセス/コマンドのプロパティです。シェルスクリプトの場合、Cプログラミング言語で設定されたモデルにも従います。 C 関数を例にとると、通常はmain次のようになります。

int main(int argc, char **argv)

実際には、コマンドライン引数の配列であるコマンドライン引数のargc数はどこにあり、ユーザーのホームディレクトリパス、実行可能ファイルを見つけることができるディレクトリのリストなどにアクセスする関数(Linuxの場合)があります。 。シェルスクリプトも同様の方法でモデル化されます。シェル用語には位置パラメータなどがありますが、むしろ位置パラメータの数があります。何について?これは、Cプログラミング言語でモデル化された実行可能ファイル自体の名前です。 C「実行ファイル」の名前になります。これは次のような場合に便利です。argvenvironman -e 7 environPATH$1$2$#$0argv[0]ほとんどのプログラミングおよびスクリプト言語

対話型シェルと非対話型シェル

私がすでに示唆していることの1つは、次の違いです。対話型および非対話型シェル。コマンドを入力するプロンプト - これは対話型であり、ユーザーと対話します。対照的に、シェルスクリプトがあるか、それを実行するとbash -c''非対話型です。

ここで区別が重要になります。実行されたシェルは、位置引数を使用して生成されたbashプロセスです。 (引用する))

対照的に、オプションで始まるスクリプトとシェルは、引数を-c利用できます。例えば、$1$2

$ bash -c 'echo $1; stat $2' sh 'Hello World' /etc/passwd
Hello World
  File: '/etc/passwd'
  Size: 2913        Blocks: 8          IO Block: 4096   regular file
Device: 801h/2049d  Inode: 6035604     Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2017-08-12 14:48:37.125879962 -0600
Modify: 2017-08-12 14:48:37.125879962 -0600
Change: 2017-08-12 14:48:37.137879811 -0600
 Birth: -

shオプションの少し珍しい点-cは、最初の位置引数を取得し、$0通常のプログラム名ではなくに割り当てるということです。

注目すべきもう一つの重要な点は、位置パラメータを「フレーム可能」と呼ぶことです。bashまず、独自の位置引数で始まりますが、これらの位置引数はとの引数にechoなりますstat。各プログラムは独自の方法でこれを理解しています。stat文字列が与えられ、Hello Worldファイルが存在しない場合、Hello Worldエラーが生成されます。bashこれは単純な文字列として扱われますが、stat文字列は既存のファイル名であると予想されます。対照的に、すべてのプログラムは環境変数がHOMEディレクトリであることに同意します(プログラマが非合理的な方法でコーディングしない限り)。


環境変数と位置パラメータを操作できますか?

技術的には両方を扱うことができますが、してはいけない環境変数を使用すると、位置引数を指定する必要があることがよくあります。シェルでコマンドを実行し、変数を前に追加できます。たとえば、次のようになります。

$ hello=world bash -c 'echo $hello'
world

export variable=valueまた、シェルまたはスクリプト内で変数を使用して環境に変数を配置することもできます。あるいは、完全に空の環境でコマンドを実行することもできますenv -c command arg1 arg2。しかし、一般的に環境を混乱させることはお勧めできません。特に、大文字変数を使用したり、既存の環境変数を上書きしたりすることはお勧めできません。これは推奨事項ですが、標準ではありません。

位置パラメータの場合、これを設定する明確な方法はコマンドに追加することですが、他の方法もあります。別の方法で設定shiftコマンドで変更できるパラメータのリスト。

おおむね両方とも異なる目的を持っていますが、理由があります。人々がこの答えを通して洞察力を得ることを願っています。私が書いたのと同じくらい読むのも面白いです。


コマンド設定に関する注意事項

マニュアルによると、setコマンドは次のように動作します(bashマニュアルで強調表示されます)。

オプションなし、各オプションの名前と値シェル変数現在設定されている変数を設定またはリセットするための入力として繰り返し使用できる形式で表示されます。

つまり、setシェル固有の変数を見てください。その一部は環境にありますHOME。たとえば、などのコマンドは、envコマンドprintenvの実行時に使用される実際の環境変数を調べます。また、見ることができますこれ

答え3

これらの$1, $2, $3, ..., ${10}, ${11}変数は位置パラメータと呼ばれ、bashのマニュアルセクションで説明されています。3.4.1

3.4.1 位置パラメータ

位置パラメータは、単一の数値ゼロではなく1つ以上の数値で表されるパラメータです。位置引数は、シェルが呼び出されるとシェルの引数から割り当てられ、set組み込みコマンドを使用して再割り当てできます。位置パラメータNは、$ {N}として引用するか、Nが単一の数字で構成されている場合は$ Nとして引用することができます。位置パラメータは、割り当てステートメントを使用して割り当てることはできません。 setおよびShift組み込みコマンドは、それらを設定および設定解除するために使用されます(シェル組み込みコマンドを参照)。位置パラメータは、シェル関数が実行されると一時的に置き換えられます(シェル関数を参照)。

複数の数値で構成される位置引数を拡張する場合は、中かっこで囲む必要があります。

$?とに関しては$0、これらは特殊パラメータ次のセクションで紹介します。3.4.2

3.4.2 特殊パラメータ

シェルはいくつかのパラメータを特別に扱います。これらのパラメータは参照用にすぎず、そのための割り当ては許可されていません。

...

($?) 最後に実行された前景パイプの終了状態に展開されます。

0

($ 0)はシェルまたはシェルスクリプトの名前に展開されます。これはシェルが初期化されるときに設定されます。 Bashがコマンドファイル(シェルスクリプトを参照)を使用して呼び出されると、$ 0がファイル名に設定されます。 Bashが-cオプション(Bash呼び出しを参照)で始まる場合、$ 0は実行される文字列の後の最初の引数(存在する場合)に設定されます。それ以外の場合は、引数0で指定されたようにBashを呼び出すために使用されるファイル名に設定されます。

答え4

いいえ、これはスクリプトのパラメータです。たとえば、次のようにスクリプトを呼び出すと:

mynicescript.sh one two three

これにより、スクリプトでこれらのパラメータを次のように使用できます。

$1 = one
$2 = two
$3 = three

$ 0はスクリプト自体の名前です。

したがって、スクリプトの外側にある場合、これらの変数は使用できません(シェル自体である/ bin / bashを表示する$ 0を除く)。

関連情報