web-dev-qa-db-ja.com

VARをサブシェルから親シェルにエクスポートする方法

Korn Shellスクリプトがあります

#!/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

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

私は知っています

. .myscript.sh

しかし、「調達」せずにそれを行う方法はありますか?ユーザーが「ソース」を忘れることが多いため。


EDIT1:「exit 0」の部分を削除する-これは私が最初に考えずにタイプしただけの

EDIT2:なぜ私はこれが必要なのかについての詳細を追加します:開発者は(簡単にするために)2つのアプリのコードを記述します:ABCとDEF。すべてのアプリは、別々のユーザーusrabcとusrdefによって運用環境で実行されているため、アプリに固有の$ BIN、$ CFG、$ ORA_HOMEなどをセットアップしています。

そう

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

等.

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

現在、スクリプトは同じアプリの並行開発などのために新しいサンドボックスも作成する必要があります。これにより、サンドボックス名などを求めてインタラクティブに行うことができます。

  • / home/justin_case/sandbox_abc_beta2
  • / home/justin_case/sandbox_abc_r1
  • / home/justin_case/sandbox_def_r1

私が検討した他のオプションは、エイリアスを作成してすべてのユーザーのプロファイルに追加することです

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

そしてそれを実行します

  • setup_env parameter1 ... parameterX

これは今ではもっと理にかなっています

9
webwesen

「できない」問題だと思います...

まず、最後に出口0があるため、そのスクリプトをソースにしたくありません。

第二に、UNIXの子プロセスが親の環境を直接変更することはできません。そうでなければ、あらゆる種類のクレイジーなことが可能になります。

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

「ラッパー」の概念について詳しく説明します。

プロダクションと開発のどちらを行うかに応じて、環境変数「OPTIONS」でPRODまたはDEVを使用してプログラム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にある実際のスヌーピープログラムの前にあり、スクリプトのexecステートメントにバイナリへの完全パスがあります。

11
chris

答えは調達です。ソーシングを使用すると、スクリプトに変数をcurrentシェルに含めることができますが、その親にすることはできません。これは本当です。exitコマンドなどを使用しないように注意する必要があります。これを行うと、現在のシェルが終了します。

「。」を使用してスクリプトを調達できます。

。 ./myscript.ksh

5
txwikinger

たぶんあなたがしようとすると...

#!/bin/bash

mknod fifo p

(
       echo 'value' > fifo &
)

VARIABLE=`cat fifo`
rm fifo

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

3
Oscar

OK、今は笑わないで。非常に迅速で非常に汚い解決策は追加することです

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

あなたのスクリプトに。

別のアプローチ。スクリプトの下位の$ Shellをexecするだけで、おそらく別のプロンプトが表示されます($ PS1を変更して、混乱を減らすために作業している環境でユーザーに通知します)。

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

Rant:全体として、そもそも奇妙な発想があったと思います。奇妙なことではないかもしれません...私はスタイルがやや非Unixだと思います。私は自分の生活の中で親に環境をエクスポートする必要はありませんでした。私はかつて同様の状況を見ました-.profileにログインして、3つの異なる環境のどれを単一のOracleアカウントに設定するかを尋ねました。悪い考えですが、結局のところ、ユーザーはSudoに移行することを好むことが判明しました(Sudoは3つの異なるoraxxxアカウントに移行しました)。私が尋ねるなら、あなたは何を達成しようとしているのですか?

1
kubanczyk