$PATHファイルと.(ソース)ファイルを一時的に設定するには?

$PATHファイルと.(ソース)ファイルを一時的に設定するには?

これについて考える。IFS実行時にのみ設定されますread

IFS='' read -r REPLY

しかし、私が次のようなことをした場合.源泉)、対応するコード行が実行された後も変数が割り当てられ変更されます。

PATH="/new_path:${PATH}" . script.sh
echo "$PATH"         # Value changed

なぜこれが起こるのですか? orに似たコマンドであるBash.のようなものです。たとえば、文書がありますか?sourcereadecho2.14.特殊組み込みユーティリティ、この行動に言及しましたか?

POSIX互換の方法で$PATH.ソース)ファイルを一時的に設定するにはどうすればよいですか?

答え1

.特別な組み込み

POSIXによると:

 2.単純コマンドで説明されているように、特別な組み込みユーティリティを呼び出す前の変数の割り当ては、組み込みユーティリティの完了後も有効なままです。これは通常の組み込みユーティリティやその他のユーティリティでは発生しません。

この特定の要件は、asを呼び出すとsh(より一般的にはposixそのオプションが有効になっている場合)、POSIXモードのbashでのみ満たされます。

削除するには詳細特別な組み込み、POSIX互換シェルでcommandプレフィックスとして使用可能commandそれ自体は一般的な組み込み関数ではありません特別な一つ。 POSIXは以下を明示的に述べています。

command_nameが特別な組み込みユーティリティの1つの名前と同じ場合、特別な組み込みユーティリティの先頭にある列挙リストの特殊属性は表示されません。他のすべての点で、command_nameが関数名ではない場合、コマンド(オプションなし)の効果は、それを省略するのと同じでなければなりません。

bash-5.1$ echo printenv PATH > file
bash-5.1$ (PATH=/; PATH=/usr/bin . ./file; echo "$PATH")
/usr/bin
/
bash-5.1$ set -o posix
bash-5.1$ (PATH=/; PATH=/usr/bin . ./file; echo "$PATH")
/usr/bin
/usr/bin
bash-5.1$ (PATH=/; PATH=/usr/bin command . ./file; echo "$PATH")
/usr/bin
/

evalまたはなどの特殊な組み込み機能の場合、これはPOSIXの間違いです。これらの組み込み機能を尊重するということは、後で再開できるよう.にするには、シェルが変数スタック型と変数の有効なローカルスコープを実装する必要があることを意味するためです。 、POSIXは特に指定しません。実際には、すべての実装、特にPOSIX仕様の基盤となるksh88では動作しないことがわかります。$varvar=value command . filevar=value command eval some-codesh

答え2

POSIX互換の方法でファイルを一時的に設定する方法は$PATH.

OPATH=$PATH PATH=...
. someSource
PATH=$OPATH

答え3

この回答はbashにのみ適用されます。 POSIXと完全互換のシェルでは動作しません。

一つの文章ではできませんか?

はい!関数で包みます。このアプローチには追加の変数は必要ありません(可変汚染を最小限に抑えます)。

ソースファイル:

$ cat script.sh 
echo "in script.sh file"

var='altered'

調達文書:

$ cat test.sh 
#!/bin/bash

var='original'

echo $PATH
echo
_() { . "$1" ; }

PATH="/tmp:${PATH}" _ script.sh
echo
echo $PATH
echo
echo "$var"

echoソースファイルのステートメントと変数は、ファイルが正常に取得されたことを$var確認するために使用されます。script.sh

変更は$PATH関数内でのみ適用されます_(より良い名前を使用できます)。$PATH宣言後は変更されません。

関連情報