2016-03-22 5 views
3

私は問題を回避しようとしていますが、あなたはサブシェルにオープンdb2接続を渡すことはできません。Shell関数はサブシェルで実行されますか

次のように私のコードの組織は次のとおりです。(my_driver.sh中)

ドライバスクリプト

# foo.sh defines baz() bar(), which use a db2 connection 
# Also the "$param_file" is set in foo.sh! 
source foo.sh 

db2 "connect to $dbName USER $dbUser using $dbPass" 

function doit 
{ 
    cat $param_file | while read params 
    do 
     baz $params 
     bar $params 
    done 
} 

doit 

私は私のコードを簡素化しましたが、上記のアイデアを与えるに十分です。私は上記を開始:私は疲れて

. my_driver.sh 

を助けない

my_driver.sh 

、私の本当の問題は、DB2接続がサブシェルでは利用できないということです

コマンドラインから手動で実行する場合:

source foo.sh 

そして、私は手動で$paramsを設定します。

baz $params 
bar $params 

そして、それは動作しません!だから、doitなどが、サブシェルからbarbazが実行されたように振る舞うようです。

私はどうにかして、db2をサブシェルに接続する方法を理解することができれば、私は喜ぶでしょう。

そうしなければ、これらのシェル関数は私がサブシェルで動作するように思えます。その周りに道がありますか?

+0

私は答えがあなたには明らかだと思います。はい、それはサブシェルにあります!環境変数を出力しようとすることで簡単にテストできます。 – raam86

+0

はい、それは可能ですが** **私は 'bar'または' baz' *を*サブシェル内で実行していますか? – lzc

+1

あなたのコードでは、 '' baz''または '' bar''がサブシェルで動く可能性はありません。おそらく彼ら自身がサブシェルでdb2コマンドを実行しますか? – dekkard

答えて

5

シェルは、関数を実行するためのサブシェルを作成しません。

もちろん、他の多くの目的のためにサブシェルを作成しますが、すべてが明白なわけではありません。たとえば、|の実装でサブシェルを作成します。

db2は、すべてのdb2コマンドが、接続を確立したdb2コマンドと同じ親を持つことが必要です。

echo "Execute db2 from PID $$" >> /dev/stderr 
db2 ... 

(。限り、DB2コマンドは、パイプまたはシェル括弧内で実行されていないとして)


一つの可能​​性のある問題を示すコードで(:あなたはのようなものを使用してPIDを記録することができそれは全く異なる症状を持つでしょう)は、非標準構文の使用です。

function f 

関数を定義するには、次のようにします。標準のシェルは

f() 

バッシュは、両方を理解して期待していますが、シェバングラインを持っていないか、あなたはshコマンドを使用してスクリプトファイルを実行した場合、あなたはbashのではないかもしれませんこれは、システムのデフォルトのシェルを使用して終了します。解決策を見つけた

+0

FYI:私はbashを使用しています。AFAIKは 'function'キーワードを使用しています(オプション)。(http://www.gnu.org/software/bash/manual/bashref.html#Shell-Functions)'> >/dev/stderr'は誤解を招くか、何らかの理由で私にとってはうまくいかないのです... 'echo hello world 2 >> /tmp/my_stderr.log>&2'? – lzc

0

が、完全にはできない、まだ次のようにdoitを変更した場合、それは動作します....

を問題を説明!

function doit 
{ 
    while read params 
    do 
     baz $params 
     bar $params 
    done < $param_file 
} 

なぜ、わからないのですか?

echo debug check with PID=$$ PPID=$PPID and SHLVL=$SHLVL 

私は戻って|かと同じ結果を得る:私はデバッグコードに固執するならば、私は...

をそれを証明することができますか。 cat $param_file | while read paramsはサブシェルを作成することを理解していますが、デバッグステートメントは常に同じPIDとPPIDを表示します。

また、この質問がunix.stackexchangeコミュニティに適していないのだろうか?

+1

デバッグコード**の 'BASH_SUBSHELL'変数は、' | 'の*右側がサブシェルであることを示しています...したがって、その後の' db2'コールはもはや親シェル内にありません! – lzc

関連する問題