バッシュとシェルスクリプトの変数の大文字の修正


191

私はすべて大文字の変数を含む多くのシェルスクリプトを実行しますが、これには重大な誤解があると常に考えていました。私の理解では、慣例により(そしておそらく以前から必要に応じて)、環境変数はすべて大文字で記述されています

しかし、Bashのような最近のスクリプト環境では、一時的な変数には小文字の名前を使用し、エクスポートされた(つまり環境)変数には大文字の名前を使用するという規則を常に優先してきました。例えば:

#!/usr/bin/env bash
year=`date +%Y`
echo "It is $year."
export JAVA_HOME="$HOME/java"

それはいつも私の考えです。このアプローチに同意または反対する信頼できる情報源はありますか、それとも純粋にスタイルの問題ですか?

回答:


262

慣例により、環境変数(PAGEREDITOR、...)と内部シェル変数は(SHELLBASH_VERSION、...)資産計上されます。他のすべての変数名は小文字でなければなりません。

変数名では大文字と小文字が区別されることに注意してください。この規則により、環境変数と内部変数を誤って上書きすることが回避されます。

この規則を守ることで、UNIXツールまたはシェルが使用するすべての環境変数を上書きすることを避けるためにそれらを知る必要がないので安心できます。変数の場合は、小文字にしてください。エクスポートする場合は、大文字にしてください。


8
+1。偶発的な上書きの良い点。私は言及するのを忘れていましたが、あなたがそれを言及した今、私はその問題だけを読んだり聞いたりしたので小文字を使うことに決めたと思います。
JasonSmith、2009年

5
大文字の変数名を使用する主な理由は、シェルコマンドとの競合を避けるためだと思いました。最近、スクリプトが変数「hostname」を使用したため、いずれかのサーバーのホスト名が誤って「=」に変更されました。
ThisSuitIsBlackNot

25
@ThisSuitIsBlackNotくだらないコードを無視して、変数は展開されるときにドルが前に付けられ、そうでないときにコマンド名と混同されない場所で使用されます。明らかに、hostname = mooを実行すると、問題が発生します。小文字の「ホスト名」を使用しているためではなく、正しい割り当て構文を使用していないためです。割り当ては、スペースなしのhostname = mooで行われます。正しいコードを前提として、変数名がコマンド名と競合することを心配する必要はありません。
lhunath

3
私がこれまで見てきたすべての教科書は、すべてのシェル変数について常にユーザー大文字です。小文字の変数名は許可されますが、大文字が慣例です。
ブライアンS.ウィルソン

3
私はこれを知らなかった、そして私はちょうど数時間を失った。のUSER="username"代わりにssh経由でいくつかのリモートコマンドを自動化するbashスクリプトでの使用user="username"。うわっ!嬉しいです。
ガブリエルステープルズ

28

一貫して命名規則があれば常に役立ちます。シェル変数の命名に役立つヒントをいくつか紹介します。

  • 特に複数のスクリプトまたはプロセス間で共有される場合は、エクスポートされた変数と定数にすべての大文字とアンダースコアを使用ます。関連する変数が目立ち、すべて大文字のBash内部変数競合しないように、該当する場合は常に共通のプレフィックスを使用してください。

    例:

    • 共通のプレフィックスを持つエクスポートされた変数: JOB_HOME JOB_LOG JOB_TEMP JOB_RUN_CONTROL
    • 定数: LOG_DEBUG LOG_INFO LOG_ERROR STATUS_OK STATUS_ERROR STATUS_WARNING
  • 単一のスクリプトまたはブロックをスコープとするすべての変数には「スネークケース」(すべて小文字とアンダースコア)を使用します。

    例: input_file first_value max_amount num_errors

    次のように、ローカル変数が環境変数と何らかの関係がある場合は、大文字と小文字を混在させて使用します。 old_IFS old_HOME

  • 「プライベート」変数および関数には、先行アンダースコアを使用します。これは、ライブラリファイル内またはファイル間で関数が変数を共有する必要があるシェルライブラリを作成する場合に特に関連します。メインコードで同様に名前が付けられている可能性のあるものと競合することはありません。

    例: _debug _debug_level _current_log_file

  • キャメルケースは避けてください。これにより、入力ミスによるバグが最小限に抑えられます。シェル変数では大文字と小文字が区別されることに注意してください

    例:inputArray thisLooksBADnumRecordsProcessedveryInconsistent_style


以下も参照してください。


1
これは、ある規則が、それはほとんど普遍的に認められています。ラクダ事件に対する根拠は完全に説得力があるわけではありません。エクスポートされた変数にSHOUTINGを使用することの推奨については、少し議論の余地があります。
Tripleee

3
私はそれが一般的な慣習であることを主張しませんでした。ほとんどのプログラマーは、シェルスクリプトでの強力な規則に従うことについて真剣に考えておらず、自分のやっていることに基づいて自分の考えを書き留めようと考えています。
codeforester

8

シェル変数を環境にエクスポートする場合は、POSIX(2018年第7版)環境変数の定義で以下を指定することを検討する価値があります。

シェルとユーティリティボリュームのPOSIX.1-2017のユーティリティで使用される環境変数名は、大文字、数字、および_ポータブル文字セットで定義された文字の下線()のみで構成され、数字で始まることはできません。

...

小文字を含む環境変数名の名前空間は、アプリケーション用に予約されています。アプリケーションは、標準ユーティリティの動作を変更せずに、この名前空間の名前を使用して環境変数を定義できます。


6

私はあなたがすることをします。信頼できる情報源はないかと思いますが、かなり広く使われている事実上の標準のようです。


1
同意する。ALL_CAPSは醜いからですが、醜いことで環境変数を際立たせるのは良いことです。
スリム

1
コーディングスタイルについてはあなたの意見に同意しますが、それが広く普及していることにはまったく同意しません。シェルスクリプトは、人々が非公式に学ぶだけの副言語の1つであるため、誰もが常にLOCATION =cat /tmp/location.txt
JasonSmith

@jhs-私は明らかに私が作業しなければならなかったシェルスクリプトで幸運でした!
ドラえもん2009年

4
「小文字を含む環境変数名の名前空間は、アプリケーション用に予約されています。」- POSIX IEEE STD 1003.1から2008のセクション8.1
tripleee

5

実際、「環境変数」という用語はかなり最近の造語のようです。KernighanとPikeは、1984年に発行された彼らの古典的な本「The UNIX Programming Environment」で、「シェル変数」のみについて語っています-インデックスには「環境」のエントリさえありません!


8
それは本の省略だと思います。getenv()、setenv()およびenvironは、UNIXバージョン7(1979)で導入されました。en.wikipedia.org/wiki/Version_7_Unix
Juliano

3
その本は大文字の変数が特別な意味を持っていることに注意するように見えます。
ashawley 2009年

3

これは非常に広く開催されている大会です。「権威」のある情報源はないかと思います。


1

環境変数とグローバル変数の両方にALL_CAPSを使用する傾向があります。もちろん、Bashには実際の変数スコープがないため、グローバルとして使用される変数の大部分(主に設定と状態の追跡)と、比較的少数の「ローカル」(カウンター、イテレーター、部分的に構築された文字列、一時)があります。


はい、私は概念的には、エクスポートされていない変数をローカルと考えています。なぜなら、Bashは子プロセスに任務を実行することを任せることが多いからです。
JasonSmith 2009年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.