プロが教える店舗&オフィスのセキュリティ対策術

shell 記述したsetenvが無効になります。

プロンプトから打ち込むとOKなのですが、
test.sh shellに
----------------------------------------------
#!/bin/csh
setenv 環境変数 環境変数パス
----------------------------------------------
などと記述し、sh test.sh でプロンプトから
実行したときのsetenvでは無効になります。

root ではなく、通常ユーザなので、管理者が
制限をしているのかもしれませんが、
ログイン時の.cshrc に記述されたsetenvは有効になって
いる様子で、パスが通らないと動かないDB用のコマンドが
ちゃんと起動します。

どなたか、ご存知の方がいらっしゃいましたら
教えてください。宜しくお願い致します。

A 回答 (3件)

『shell 記述したsetenvが無効になります。


正しく設定されているはずですよ。
シェルスクリプトを下記の用に変更してご確認ください。

#!/bin/csh
setenv 環境変数 環境変数パス
echo "環境変数 の値は $環境変数 です。"

正しく設定されている事が確認できると思います。

『などと記述し、sh test.sh でプロンプトから
実行したときのsetenvでは無効になります。』

それは違う所を見てますよ。
環境変数はプロセスが持っています。
シェル上からコマンドを起動すると、そのコマンドはシェルの子プロセス(対話シェルとは別のプロセス)として起動されます。
シェルスクリプト内で設定した環境変数は子プロセスの環境変数領域に値を設定します。(設定する場所はシェルスクリプトから見たら親プロセス[対話シェル]の環境領域ではなく子プロセスの環境領域です)
シェルスクリプトの終了で子プロセスは終了し開放されますので子プロセスで設定した値も廃棄されます。


『root ではなく、通常ユーザなので、管理者が
制限をしているのかもしれませんが、』
root であろうが一般ユーザであろうが同じ動作をします。


『ログイン時の.cshrc に記述されたsetenvは有効になって
いる様子で、パスが通らないと動かないDB用のコマンドが
ちゃんと起動します。』
ログイン時や csh 起動時に .cshrc を読み込む時にはシェルは子プロセスを起動せず自身の環境で実行しますので、そこでの環境操作は対話シェルに反映されます。

また、パスが通らないと動かないDB用のコマンドはちゃんと動くはずですよ。(下記のシェルスクリプトで、スクリプトを動かしている子プロセスの環境が迫っていされ動作する事が確認できるでしょう)

#!/bin/csh
setenv 環境変数 環境変数パス
DB用のコマンド

上記では起動した子プロセスないの環境(環境変数設定が行われている)を使っているので DB用のコマンドが意図通り動くと思いますよ。

多くのシェルは子プロセスを起動しその上で動かしたり、自身が直接動かしたりという事を区別して行います。シェルのオンラインマニュアル等にも違いがしっかり記載されていますのでご確認ください。
プロセスの環境に影響を与えるコマンド(例えば cd )でも同様な事が起こりますので意識してお使いください。

% ( setenv 環境変数 環境変数パス )

※ 上記方法(カッコで囲み)で起動するとシェルスクリプトと同様子プロセスを起動しそのプロセスで環境変数を設定、終了と共にその環境を破棄しますから直後に環境変数を確認しても設定されてない様に見えるはずです。(実際には設定した環境が破棄されてしまっているだけなのですが)

cd や setenv はビルトインコマンド(内部コマンド)としてシェル内に実装されています。これは動作中のシェル自身の環境を操作する必要があるからです。外部コマンドは必ずプロセスを起動して実行されますので外部コマンドとして追加・作成したソフトの中で親プロセスの環境を操作する事は通常できません。

スクリプトを下記の方法で起動すればシェルは自身の環境でスクリプトを読み込み実行しますので内部コマンドによる環境へ影響の与えるコマンドの実行結果が起動した親プロセスに反映されます。

標準シェル系
$ . setup_script.sh

Cシェル系
% source setup_script.csh

標準シェル系の . で起動する手法は /etc/rc 等の起動時システム設定等でも多用されていると思いますので読んでみると良い(学べる事が多い)でしょう。

この回答への補足

早々のご回答ありがとうございます。

私の記述の方法がいけなかったのですが、
sh test.sh と実行した後に プロンプトからsetenvの内容が
反映されなかったということでは無く、
【setenv コマンドそのものがエラーになる】と言いたかったのです。
実際のshell記述では、10通り以上の変更を加え、下記の記述も
行っています。
----------------------------------------------
#!/bin/csh
setenv 環境変数 環境変数パス

echo $環境変数 > test.log ←こんな記述
----------------------------------------------
で、これをログインした時のコマンド上で、
# sh test.sh
と実行すると、cat test.log で【環境変数パス】が表示されますが、
crontab で実行すると、setenv に対しては【そのコマンドは無い】
と表示され、test.log には、半角1byteのみが記述されていたのです。
なので、crontab で指定した.sh 内部に記述したsetenvコマンドは、
無効になるのでしょうか? という内容に訂正させて頂きます。

記述があいまいですいませんでした。

補足日時:2008/11/10 16:04
    • good
    • 0

シェルスクリプト 1 行目の #! /bin/csh の様な行をインタプリタ(指定)行と呼びます。


インタプリタ行は実行権を付けたファイルを起動した時使われます。
今回の質問では下記の通り起動してますので
sh test.sh
そのスクリプトはsh(標準シェル)で実行されます。
setenvはcshの内部コマンド(builtin コマンド)なのでshにはありません。
ですから、
## などと記述し、sh test.sh でプロンプトから
## 実行したときのsetenvでは無効になります。
というのは間違いで、 setenv を実行したけどエラーとなり何もされなかった
というのが正しいです。

今回、 sh test.sh で実行しsetenv がエラーになったと思われますが、csh test.sh で実行してみてください。
そうすれば、setenv コマンドは意図通りに処理される(csh スクリプトとして処理されますので)と思います。

また、
sh -x test.sh
としてみてください。shとして実行した時の細かな動作が理解(調査)できると思います。

今回の様に まるで質問を変える場合には一旦終了し新たな質問として作成しましょう。
そうすれば、新たな質問として多くの方の目に止まります。(新たな質問ではなく多くの方が一度見て助言できないと判断したままとなっていますので、見てくださる方が非常に少なくなっているはずですし、解決できる可能性のある方を減らすのは回答をいただきたい質問者としては損な事だと思います)
また、後で同じ問題に困った人が見る時にもタイトルと中身が変わってしまっている質問は見付難いです。
せっかく公開されているQ&Aが役立ちません。

前の返事として関連している事を多く助言していると思いますのでしっかり理解してくださればありがたいです。
せっかく書いた事ですから。
    • good
    • 0
この回答へのお礼

saijyo_739様。
回答、ありがとうございます。
解決致しました。

登録、質問共に初めてで、記述の方法すらよくわかりませんでした。
その辺りの事まで教えて頂いて、とても助かります。

また、質問することになると思われるので、
宜しくお願い致します。

何よりも、早い回答に感謝しております。
心より、ありがとうございました。

お礼日時:2008/11/10 21:21

> sh test.sh でプロンプトから実行したときのsetenvでは無効になります。



それは、そのスクリプトの中での設定の話ですから
たとえば、cshを起動しているときにコマンドラインからcshを起動してsetenv しても、logoutして元のcshに戻ったときにはsetenvした内容は消えてますよね

testというファイルに、
setenv 環境変数 環境変数パス
を書いて、
source test
を実行してみましょう
    • good
    • 0
この回答へのお礼

早々のご回答ありがとうございます。

私の記述方法に誤りがあり、他の方への再度の質問で
解決いたしました。

ご指導、ありがとうございました。

お礼日時:2008/11/10 21:25

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!