- ベストアンサー
シェルスクリプトの実行、「source」と「.」の違いについて
bashのシェルスクリプトを書いています。 当方、Mac Snow Leopard を使っているため、seq コマンドがデフォルトでは使えません。 そこで、.bashrc 内に、seq 関数をあらかじめ自分で定義して、他で使い回したいと思っています。 .bashrc の中に、 function seq() { i=$1 while [ $i -le $2 ] ; do echo $i let i=$i+1 done } と、関数を定義しました。 seq 関数をターミナル上で実行すると、 >seq 0 2 0 1 2 と正しく、表示されます。次に、 #!/bin/sh seq 0 2 と記述したシェルスクリプト(temp.sh)を「source」で実行すると、 >source temp.sh 0 1 2 と正しく、表示されますが、「.」で実行すると、 >./temp.sh ./temp.sh: line 2: seq: command not found と言われます。 どのような理由によってこの違いが出るのでしょうか??
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
追記 source は現在のシェルで実行し、結果がそのまま現在のシェルに適応されます。 今回の temp.sh なら > source temp.sh は > seq 0 2 と入力したのと同等ということになります。 > ./temp.sh この . はコマンドではなく、 temp.shへのパスを指定するものです。 実行ファイル名だけでコマンドとして実行できるのは、環境変数PATHで指定したディレクトリにあるものだけです。それ以外は、その実行ファイルへの絶対パス、または相対パスが必要となります。 これは、カレントディレクトリにある実行ファイルも例外ではありません。 環境変数PATHに . が無い場合は、 ./ファイル名 と相対パスを指定する必要があります。 (この点は、常に . がPATHにあるように振る舞うMS-DOSやコマンドプロンプトとは違います) 逆に、PATH上にあれば(例えば、 PATH=$HOME/bin:(以下略)となっている時の $HOME/bin )、 temp.sh とファイル名だけで実行できます。 また、こうしたコマンドは新規プロセスで実行されますので、環境変数を除いて、現在の設定は継承されません。 対話的ではないbashや、 shとして起動された bash は .bashrcを読まないので、そこに書いてあることは無効となります。
その他の回答 (5)
- corgi12kg
- ベストアンサー率51% (28/54)
補足します . ./temp.sh ドット スペース ドット スラッシュ スクリプトファイル名 最初のドットはドットコマンド 次のドットはカレントパスを意味するメタ文字 ということです
お礼
シェルスクリプトの実行において、 「./temp.sh」と「. ./temp.sh」「source temp.sh」の意味が違うことを初めて知りました。ありがとうございました。
- corgi12kg
- ベストアンサー率51% (28/54)
ドット実行ができていないのでは? 正 . ./temp.sh 誤 ./temp.sh
お礼
なるほど、確かに、 . ./temp.sh であれば通りますね。 今まで、シェルスクリプトの実行は、 「source temp.sh」か「./temp.sh」としてやっていましたが、 「source temp.sh」と同等なのは「. ./temp.sh」のようですね。 なぜ、./temp.shで通らないかは、 回答番号:No.5さんの回答で了解しました。 ありがとうございます。
- kmee
- ベストアンサー率55% (1857/3366)
seqだけが目的なら、 GNU coreutils をインストール、という方法もあります。 ソースからのビルドになります。 お手軽なのは、 MacPorts をインストールして sudo port install coreutils を実行することです。
お礼
ありがとうございます。 それは、最もなのですが、 今回は、「source」 と 「./」の違いについて知りたいと思っています。
- notnot
- ベストアンサー率47% (4900/10358)
すいません。勘違い。 シェルスクリプト実行として起動されたbashは、~/.bashrc は読みません。 ファイルの先頭に、source ~/.bashrc とでも書くか、seq を関数としてでなく コマンド(シェルスクリプトファイル)として作るか。
お礼
>シェルスクリプト実行として起動されたbashは、~/.bashrc は読みません。 しかし、 source temp.sh として実行した場合は ~/.bashrc を読んでいるので、 seq 関数が使えます。 source temp.sh でseqが通り ./temp.shで通らない理由は、 回答番号:No.5 さんの回答でわかりました。 ありがとうございました。
- notnot
- ベストアンサー率47% (4900/10358)
>#!/bin/sh bashでなく/bin/shを起動しているからでは?
お礼
ありがとうございます。 試してみましたが、 >#!/bin/sh >#!/bin/bash 共に同じ結果でした。
お礼
今まで、 「source temp.sh」と「./temp.sh」は同じものとして使ってきましたが、 こういった違いがあると初めて知りました。 試しに、適当なシェルスクリプト temp.sh (#!/bin/bash \n sleep 100) 実行時に 「ps u」をしてみると、 「./temp.sh」実行時には、 /bin/bashが新たにプロセスとして立ち上がっていましたが、 「source temp.sh」「. ./temp.sh」実行時には、 それが無く、既存のプロセス内(bash)で動いているようでした。 そして、./temp.sh により、新たに立ち上がったプロセスの方では、 環境変数等以外の設定は継承されず、さらに、~/.bashrcは読み込まれないということですね。 わかりやすい説明をどうもありがとうざいました。