ファイルをインポートする前にファイルが存在することをいつ(またはなぜ)確認する必要がありますか?

ファイルをインポートする前にファイルが存在することをいつ(またはなぜ)確認する必要がありますか?

ファイルをインポートしようとすると、ファイルが存在しないというエラーが表示され、何を修正するのかわかりませんか?

例えば、不揮発性これを設定ファイル/ rcに追加することをお勧めします。

export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm

上記のようにnvm.sh存在しない場合、「自動エラー」が発生します。しかし、試してみると. "$NVM_DIR/nvm.sh"結果が得られますFILE_PATH: No such file or directory

ベストアンサー1

POSIXシェルには特別な.組み込みコマンドがあり、失敗するとシェルは終了します(たとえば、一部のシェルではbashPOSIXモードでのみ実行されます)。

エラーはシェルによって異なります。これらすべてがファイルを解析するときに構文エラーで終了するわけではありませんが、ほとんどはソースファイルが見つからないか開くことができないときに終了します。ソースファイルの最後のコマンドがゼロ以外の終了ステータスを返す場合(errexitもちろん、そのオプションがオンになっていない場合)、どのコマンドも終了することを知りません。

ここで:

[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"

この場合、ファイルが存在する場合はソースをインポートし、ファイルが-s存在しない場合(またはここで空の場合)はファイルソースをインポートしないようにします。

つまり、ファイルが存在しない場合はエラー(POSIXシェルの致命的なエラー)と見なされるべきではなく、ファイルはオプションと見なされます。

ファイルが読み取れない、またはディレクトリの場合、または(一部のシェルで)ファイルの解析中に構文エラーが発生した場合、これは依然として(致命的な)エラーであり、報告する必要がある実際のエラー条件になります。

一部の人々は競争条件があると主張しています。ところがそれを意味するのは、との間にファイルを削除するとシェルがエラーで終了するということですが、[スクリプト.の実行中にこの固定パスファイルが突然消えるため、これをエラーと考えるのが妥当だと思います。ランニング。

一方、

command . "$NVM_DIR/nvm.sh" 2> /dev/null

どこから¹がcommand削除されましたか?特別なコマンドの属性.(エラーが発生したときにシェルを終了しない)は影響を与えません。

  • エラーを非表示にし、.ソースファイルで実行されるコマンドのエラーも非表示にします。
  • また、無効な権限を持つファイルなどの実際のエラー条件を非表示にします。

他の一般的な構文(たとえば、オプションの環境ファイルを指定するDebianシステムの未変換initスクリプトを参照)は次のとおりですgrep -r /etc/default /etc/init*systemdEnvironmentFile=-/etc/default/service

  • [ -e "$file" ] && . "$file"

    ファイルが存在することを確認し、空の場合はインポートします。開くことができない場合でも、それは致命的なエラーです(それが存在していたか存在していても)。[ -f "$file" ](存在し、次のようなより多くのバリエーションを見ることができます。定期的なファイル)、[ -r "$file" ](読み取り可能)、またはそれらの組み合わせです。

  • [ ! -e "$file" ] || . "$file"

    少し良いバージョンです。ファイルが存在しないのが正常であることをより明確にします。これはまた、$?最後の命令実行の終了状態が反映されることを意味します$file(以前の場合を取得すると、それが存在しなかったためか、命令が失敗したためか1わかりません)。$file

  • command . "$file"

    ファイルが存在すると予想されるが説明できない場合は終了しないでください。

  • [ ! -e "$file" ] || command . "$file"

    上記の組み合わせ:ファイルが存在しないかどうかは重要ではありません。 POSIXシェルの場合、ファイルを開く(または解析)失敗が報告されますが、致命的ではありません(より適切である可能性があります~/.profile)。


1注:ただし、これはエミュレーションを除いて使用zshできませんcommandshKorn シェルでは、source実際には Korn シェルのエイリアスであり、command .特別ではないバリアントです。.

おすすめ記事