dポイントプレゼントキャンペーン実施中!

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
と言われます。
どのような理由によってこの違いが出るのでしょうか??

A 回答 (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を読まないので、そこに書いてあることは無効となります。
    • good
    • 1
この回答へのお礼

今まで、
「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は読み込まれないということですね。
わかりやすい説明をどうもありがとうざいました。

お礼日時:2010/04/17 20:31

補足します



. ./temp.sh

ドット スペース ドット スラッシュ スクリプトファイル名

最初のドットはドットコマンド
次のドットはカレントパスを意味するメタ文字

ということです
    • good
    • 1
この回答へのお礼

シェルスクリプトの実行において、
「./temp.sh」と「. ./temp.sh」「source temp.sh」の意味が違うことを初めて知りました。ありがとうございました。

お礼日時:2010/04/17 20:18

ドット実行ができていないのでは?



正 . ./temp.sh
誤 ./temp.sh
    • good
    • 0
この回答へのお礼

なるほど、確かに、
. ./temp.sh
であれば通りますね。
今まで、シェルスクリプトの実行は、
「source temp.sh」か「./temp.sh」としてやっていましたが、
「source temp.sh」と同等なのは「. ./temp.sh」のようですね。
なぜ、./temp.shで通らないかは、
回答番号:No.5さんの回答で了解しました。
ありがとうございます。

お礼日時:2010/04/17 20:16

seqだけが目的なら、 GNU coreutils をインストール、という方法もあります。


ソースからのビルドになります。

お手軽なのは、 MacPorts をインストールして
sudo port install coreutils
を実行することです。
    • good
    • 0
この回答へのお礼

ありがとうございます。
それは、最もなのですが、
今回は、「source」 と 「./」の違いについて知りたいと思っています。

お礼日時:2010/04/17 20:12

すいません。

勘違い。
シェルスクリプト実行として起動されたbashは、~/.bashrc は読みません。
ファイルの先頭に、source ~/.bashrc とでも書くか、seq を関数としてでなく コマンド(シェルスクリプトファイル)として作るか。
    • good
    • 1
この回答へのお礼

>シェルスクリプト実行として起動されたbashは、~/.bashrc は読みません。
しかし、
source temp.sh 
として実行した場合は ~/.bashrc を読んでいるので、
seq 関数が使えます。
source temp.sh でseqが通り
./temp.shで通らない理由は、
回答番号:No.5 さんの回答でわかりました。
ありがとうございました。

お礼日時:2010/04/17 20:11

>#!/bin/sh



bashでなく/bin/shを起動しているからでは?
    • good
    • 0
この回答へのお礼

ありがとうございます。
試してみましたが、
>#!/bin/sh
>#!/bin/bash
共に同じ結果でした。

お礼日時:2010/04/17 03:50

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