サブシェルから親シェルに VAR をエクスポートするにはどうすればよいですか?

サブシェルから親シェルに VAR をエクスポートするにはどうすればよいですか?

Kornシェルスクリプトがあります

#!/bin/ksh
# set the right ENV
case $INPUT in
abc)
  export BIN=${ABC_BIN}
  ;;
  def)
  export BIN=${DEF_BIN}
  ;;
  *)
  export BIN=${BASE_BIN}
  ;;
esac
# exit 0 <- bad idea for sourcing the file

現在、これらの変数はサブシェルでのみエクスポートされていますが、親シェルでも設定したいので、プロンプトではそれらの変数が正しく設定されたままになります。

私は知っている

. .myscript.sh

しかし、「source」なしでそれを実行する方法はありますか? ユーザーは「source」を忘れることが多いです。


編集1: 「exit 0」の部分を削除しました。これは私が何も考えずに入力しただけです。

編集2: これが必要な理由について、さらに詳しく説明します。私の開発者は、(簡単にするために) 2 つのアプリ (ABC と DEF) のコードを書きます。すべてのアプリは、本番環境では別々のユーザー usrabc と usrdef によって実行されるため、アプリ固有の $BIN、$CFG、$ORA_HOME などが設定されています。

それで

  • ABC の $BIN = /opt/abc/bin # 上記のスクリプトの $ABC_BIN
  • DEF の $BIN = /opt/def/bin # $DEF_BIN

現在、開発ボックスでは、開発者は自分のユーザー アカウント「justin_case」で ABC と DEF の両方を同時に開発できます。また、開発者が ENV 変数設定を切り替えられるように、ファイル (上記) をソースにするようにしています。($BIN は、一度に $ABC_BIN を指す必要があり、その後、$BIN=$DEF_BIN に切り替える必要があります)

ここで、スクリプトは同じアプリの並行開発などのために新しいサンドボックスも作成する必要があります。これにより、サンドボックス名などを尋ねながら対話的に実行できるようになります。

  • /home/justin_case/サンドボックス_abc_beta2
  • /home/justin_case/サンドボックス_abc_r1
  • /home/justin_case/サンドボックス_def_r1

私が検討した他の選択肢は、エイリアスを書いてそれをすべてのユーザーのプロフィールに追加することです

  • エイリアス 'setup_env=. .myscript.sh'

そしてそれを実行する

  • setup_env パラメータ1 ... パラメータX

今ではそれが私にとってより意味を成すようになった

答え1

それは「どうしようもない」問題だと思います...

まず、最後に exit 0 があるため、そのスクリプトをソース化することは望ましくありません。

第二に、Unix の子プロセスは親の環境を直接変更できません。そうしないと、あらゆる種類のおかしなことが可能になります。

デフォルトのプロファイルまたは bashrc ファイルを使用して環境に何かを追加したり、実行しようとしているプログラムのラッパーを作成したりできますか?

「ラッパー」の概念について詳しく説明させてください。

実稼働か開発かに応じて、環境変数「OPTIONS」に PROD または DEV を指定して snoopy プログラムを実行するとします。設定されていない場合、snoopy は実稼働と開発のデータベースを消去するなど、奇妙な動作をします...

「snoopy」を snoopy.bin (または .snoopy.bin) に名前変更します。

次に、同じ場所に「snoopy」という名前の次の内容を含むスクリプトを配置します。

#!/bin/sh

export OPTIONS

case "$OPTIONS" 
in
  PROD) ;;
  DEV) ;;
  *) OPTIONS=DEV ;;
esac

#the binary is actually named snoopy.bin 

exec "$0.bin" "$@"

実際のファイルをいじりたくない場合は、このスクリプトを、ユーザーの PATH 内の実際の snoopy プログラムより前になるファイルシステムのどこかに配置し、スクリプトの exec ステートメントにバイナリへの完全なパスを指定します...

答え2

答えはソースです。ソースを使用すると、スクリプトに変数を含めることができます。現在シェルは作成できますが、その親シェルは作成できません。確かに、exit コマンドなどを使用しないように注意する必要があります。そうしないと、現在のシェルが閉じられてしまいます。

「.」を使用してスクリプトをソースすることができます。

。 ./myscript.ksh

答え3

試してみると、もしかしたら...

#!/bin/bash

mknod fifo p

(
       echo 'value' > fifo &
)

VARIABLE=`cat fifo`
rm fifo

正確には変数のエクスポートではありませんが、親プロセスとの基本的な通信を提供できます。

答え4

笑わないでください。非常に簡単で汚い解決策は、

echo "Please copy and paste this command:"
echo ""
echo "export BIN=\"$BIN\""

あなたのスクリプトに。

別のアプローチexecスクリプト内の従属 $SHELLのみで、プロンプトは異なる可能性があります (混乱を減らすために、ユーザーがどの環境で作業しているかを通知するように $PS1 を変更します)。

別のアプローチ(私のお気に入り)。ユーザーがスクリプトをソース化することを忘れるのはなぜでしょうか? ソース化はまさに標準的な方法です。おそらく、ユーザーに思い出させる良い方法は、最初の行 ( #!/bin/sh) を削除してからchmod a-xそれを削除することです。その後もソース化することはできますが、明らかに誤って実行されることはありません。

暴言: 全体的に見て、そもそも奇妙なアイデアを思いついたと思います。奇妙ではないかもしれませんが... スタイルが Unix らしくないと言えるでしょう。私はこれまで、環境を親にエクスポートする必要は一度もありませんでした。似たような状況を一度見たことがあります。ログイン .profile が、単一の Oracle アカウントに 3 つの異なる環境のどれを設定するかを尋ねてきたのです。これは悪いアイデアで、結局、ユーザーは sudo への移行を好んだことが判明しました (3 つの異なる oraxxx アカウントに sudo を実行しました)。何を達成しようとしているのですか?

関連情報