出産前後の痔にはご注意!

シェルスクリプト内のcdコマンドで、カレントディレクトリを変えるにはどうしたらいいか?をどうか教えて下さい。

MS-DOSのバッチファイル内で"cd XXXXX"と書き実行した時の動作を、UNIX(CygWin)環境でも行いたいです。
が、シェルスクリプトは(サブシェルで動く為)カレントディレクトリが変わってくれません。aliasコマンド等でいろいろ実験しましたが、DOSバッチファイルのように「バッチファイル単体でディレクトリ移動が出来る方法」を探し出せませんでした。

極めて初歩的とは存じますが、どうか宜しくお願い致します。

A 回答 (3件)

カレントディレクトリはプロセスの属性なので、子プロセス内で変更しても親には影響しないというのはおわかりのようなので、親プロセスの中で実行すればいいわけです。



今実行しているシェルプロセスの中でスクリプトファイルに書かれたコマンド群を実行するには、ピリオドコマンドもしくはsourceコマンドを使います。

. スクリプトファイル名

source スクリプトファイル名

で実行してください。

別の方法としては、やりたいことをスクリプトファイルに書くのでなく、aliasや関数で定義するという方法もあります。
たとえば引数がディレクトリならそこにcdする関数は、
cddd() { test -d $1 && cd $1; }
と.bashrcなどで定義します。
    • good
    • 2
この回答へのお礼

接頭辞shの代わりに.を使うように致します。最も単純に実現できました。どうも有難うございます。

お礼日時:2007/04/19 14:58

DOSのバッチファイルとどうような処理をさせようとすると,sourceコマンドを使うことになるかと思います.



例えば,cdを含むスクリプトscr.sh を書いておいて,
source ./scr.sh
とやるとか.
(で,これをaliasで別名を割り振ることになるかと.その場合, scr.sh は絶対パスを指定する必要が出てきますが)

この回答への補足

期待通りになりました。どうも有難うございました。
が、No3の方がより単純な . の方法を教えてくださりました。
それを使おうと思います。

補足日時:2007/04/19 14:56
    • good
    • 1

(cd hoge; command1; command2;...)


のように()でsub shellを起動後cdします。
    • good
    • 0

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

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qsedの置換文字に変数を使用したいのですが・・・

あるファイルの特定の文字を変換し、上書きをする処理を行いたいのですが、sedの置換文字に変数が渡せなくて困っています。

例:
X="a"
Y="b"
echo test.txt | sed 's/${X}/${Y/g}' >test.txt

sedでは置換文字に${X}といった変数を使用することはできないのでしょうか?

Aベストアンサー

' ・・・' で囲まれた中の$はそのままドルマークです。変数展開をするなら、'・・・'で囲んではいけません。

何も囲まないか、"・・・"で囲むかです。

Qapt-get install ****** でinstallしたものをuninstallするには?

御世話になります。
vncserverだけをinstallするつもりが
誤って
apt-get install vncとうってしまいました。
これをuninstallしたいのですが
どのようにすればよろしいでしょうか?

教えて下さい。

Aベストアンサー

# apt-get remove パッケージ名
では、設定ファイルは削除されずに残ります。

完全に削除するときは、
# apt-get --purge remove パッケージ名
です。

Qシェルスクリプトの実行、「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
と言われます。
どのような理由によってこの違いが出るのでしょうか??

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

...続きを読む

Aベストアンサー

追記

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を読まないので、そこに書いてあることは無効となります。

追記

source は現在のシェルで実行し、結果がそのまま現在のシェルに適応されます。
今回の temp.sh なら
> source temp.sh

> seq 0 2
と入力したのと同等ということになります。

> ./temp.sh
この . はコマンドではなく、 temp.shへのパスを指定するものです。
実行ファイル名だけでコマンドとして実行できるのは、環境変数PATHで指定したディレクトリにあるものだけです。それ以外は、その実行ファイルへの絶対パス、または相対パスが必要となります。
これは、カレントディレクトリにある実行...続きを読む

Qshellスクリプトから別のshellスクリプトを呼び出す方法

今現在VineLinux4.1をサーバとして起動させております。
その関係もありまして維持としてシェルを動かす事はある意味必須の状態です。
本題はAと言うスクリプトからBと言うスクリプトを呼び出す方法がわかりません。
試してみた方法はsourceで呼び出す方法です。
A.shの中身を以下とすると

#!bin/bash
echo ="B.shを呼び出します"
source B.sh
echo ="シェルスクリプトを終了します"
exit 0

上記のようにした場合、最初のecho文は出力され、B.shの内容を一通り終えると最後のechoは出力されずA.shは完了しません。
ごくごく基本的なことかもしれませんが、うまく検索にも引っ掛けられなかったので、ご質問させていただきます。
よろしくお願い致します。

Aベストアンサー

#2です。

>cshは=の前後にスペースが入るかと思いますが、今回はbashを指定しておりますので。

cshの何のことを言ってるのかわかりませんが、例えばbashで、
echo="シェルスクリプトを終了します"
は、echoコマンドじゃなくて、echo というシェル変数に「シェルスクリプトを終了します」という文字列をセットするコマンドになります。当然何も表示されません。

>A.shとB.shは単独で正常に稼動できる状態です。

B.shが単独で正常に動いているように思えることは、B.shに問題がないことを意味しません。
例えば、B.sh をexitで終了したりするとそこでbashは終了するわけだし。

>質問の例はあくまで例ですが、

書かれているA.shに問題がなさそうなので、B.shの中に原因があると想像しました。
現象が発生する最小限の、A.sh と B.sh の内容をすべて正確に書いてください。

今気づきましたが、A.sh の最後に無意味なexit 0がありますが、もしかして、B.shの最後にもexit 0が?

source コマンドは、その場所に指定したファイルの内容を挿入するコマンドです( C の #include 相当 )。もし、新たにbashプロセスを起動して、そこでB.shを動かしたいなら、
bash B.sh
です。他には#1の方が書いた方法もあります。

#2です。

>cshは=の前後にスペースが入るかと思いますが、今回はbashを指定しておりますので。

cshの何のことを言ってるのかわかりませんが、例えばbashで、
echo="シェルスクリプトを終了します"
は、echoコマンドじゃなくて、echo というシェル変数に「シェルスクリプトを終了します」という文字列をセットするコマンドになります。当然何も表示されません。

>A.shとB.shは単独で正常に稼動できる状態です。

B.shが単独で正常に動いているように思えることは、B.shに問題がないことを意味しませ...続きを読む

Qgrepで検索文字列が完全一致した行だけ取り出す方法

grepの文字列検索で検索文字列が単語として、完全一致した行だけ取り出す方法はないでしょうか?

通常は
grep hoge hoge.txt

と打つと、hogeが含まれる行が出力されますが、今回は含まれる行ではなくて完全に文字列が一致した行だけ取り出したいのです。

例えばhoge.txtの中に
cc ghoge
kkl hogem
jjll hoge
という3行があったとしたら最後の行でhogeという文字が空白で区切られた行だけ取り出したいのです。

何かよい方法があれば教えてください

Aベストアンサー

-w オプションじゃだめですか?

参考URL:http://www.linux.or.jp/JM/html/GNU_grep/man1/grep.1.html

Qシェルスクリプト実行で”そのようなファイルやディレクトリはありません”と出ます。

以下の単純なシェルスクリプトを実行しようとしています。
-------------------
#!/bin/sh
echo ok
-------------------
そのとき、
bad interpreter: そのようなファイルやディレクトリはありません
と出てしまいます。

・which sh で確認すると /bin/sh です。
・Windowsで作ったファイルをFTPのアスキーモードで転送しています。

(ものすごく単純なミスをしてるのかもしれませんが、)
よろしくお願いします。

Aベストアンサー

1行目の「/bin/sh」のうしろにCRが入っていると、このような現象が発生します。
FTPの転送モードが間違いなくアスキーモードになっているか、
転送後のファイルにCRがついていないかなど、再度確認してみてください。

CR以外のコントロールコードや全角スペースなどがついていても似た現象が起こります。
その場合はエラーメッセージが多少異なるはずですが、併せて確認しておくと良いかと思います。

Q起動しているサービスを確認するコマンド

初歩的な質問で恐縮ですが、ご教示いただけますと幸いです。

起動しているサービスを確認するために以下の2つのコマンドを打ってみるのですが、結果(出て来るサービス名)が違います。
このコマンドの違いについてご教示いただけますでしょうか。

(1)service --status-all
(2)chkconfig --list

Aベストアンサー

(1)service --status-all

サービスの現在のステータスを調べるコマンド

(2)chkconfig --list

OSのブート時に自動起動するサービスを調べるコマンド

違いが出るのは、
・ブート後に手動あるいは他のコマンドから起動したサービス
・ブート後に手動あるいは他のコマンドから、あるいはエラーで停止したサービス
・ブート後に実行はされるがすぐに停止して常駐しないサービス (ntpdate とか)

あるいは、(1)ではサービス名が表示されない物もあるので、どのサービスがどんなステータス出力をするのか知っておく必要もありますね。(service network statusとか)

Qシェルスクリプトでファイル内の数値文字列を数値として扱うには

失礼します。
シェルスクリプトでファイル内のテキスト(数値文字列)を取得して、それを使って計算するにはどうすれば良いでしょうか?

str:ファイル内のテキスト(数値文字列)

res=$(( $str + 1 ))

・エラー
")syntax error: invalid arithmetic operator (error token is "


よろしくお願いします。

Aベストアンサー

bashをご使用と判断して

res=$(( $str + 1 ))
ではなく、
res=$(( str + 1 ))
だと思います。

> exprもやってみたのですが、処理が遅くなるので使いません。
興味があって以下のシェルで検証してみました。

#!/bin/bash

str=1
i=0

echo 'Using $((str + 1))'
date '+%H:%M:%S.%N'

while [ $i -lt 10000 ]
do
str=$(( str + 1))
i=`expr $i + 1`
done

date '+%H:%M:%S.%N'

exit

$ ./test.sh
Using $((str + 1))
09:18:46.290418000
09:18:56.929345000
これをexprに書き換えたところ
$ ./test2.sh
Using expr
09:19:00.302748000
09:19:19.259990000

exprだと19秒ですが、$(( 演算 )) だと10秒程度なので、演算が多くなれば確かにexprは不利ですね。

bashをご使用と判断して

res=$(( $str + 1 ))
ではなく、
res=$(( str + 1 ))
だと思います。

> exprもやってみたのですが、処理が遅くなるので使いません。
興味があって以下のシェルで検証してみました。

#!/bin/bash

str=1
i=0

echo 'Using $((str + 1))'
date '+%H:%M:%S.%N'

while [ $i -lt 10000 ]
do
str=$(( str + 1))
i=`expr $i + 1`
done

date '+%H:%M:%S.%N'

exit

$ ./test.sh
Using $((str + 1))
09:18:46.290418000
09:18:56.929345000
これをe...続きを読む

Q端末(ターミナル)から端末を起動しコマンドを実行

お世話になります.
※端末=ターミナルです.
早速ですが,Ubuntu(Linux)の端末1から別の端末2を呼び,端末1から呼び出した新しい端末2の上でコマンドを実行する方法はありませんでしょうか?

調べてところ,
$ gnome-terminal
のオプションで,「 -e, --command」 や「 -x, --execute 」を利用することで,端末2を起動しながらコマンドを実行できる様です.(gnome-terminal --help 参照)

しかし,実際に試したUbuntu8.10では,端末2が起動するものの,その上で指定したコマンドが実行されません.

やり方をご存知の方がいましたら,ご教授よろしくお願いいたいます.

Aベストアンサー

書式を勘違いされているような?

普通に
gnome-terminal -e top &
といった形で実行できませんか?

Qpingでポートの指定

pingでIPアドレスを指定して、通信できるかどうかというのは
よく使いますが、pingでポートを指定して応答するかどうかは調べられるのでしょうか?

よろしくお願いします

Aベストアンサー

pingを含むICMPというプロトコルは、OSIの7レイヤで言うところのL2(同一セグメント内通信)とL3(IPルーティングされた通信)の両方にまたがる、ちょっと珍しいプロトコルです。

IPアドレスは指定できますが、別サブネットに属するIPアドレスに到達できればL3通信、できなければゲートウェイと呼ばれる同一サブネットに属する中継装置からの回答を得るという点でL2(MAC通信ではなく、同一セグメント内通信という意味)通信です。

ポート番号はL4で使用されるアドレスですから、L4機能の疎通確認はping(を含むICMP)ではできません。

FTPの疎通確認であれば、クライアントからサーバに対するTCP/21通信(FTP-CMD)が可能であること(サーバからクライアントへのTCP/21からの応答を含む)+サーバからクライアントに対するTCP/20通信(FTP-DATA)が可能であること(クライアントからサーバへのTCP/21からの応答を含む)が必要でしょう。

監視ソフトによるものであれば、
・クライアントからサーバへのログイン(TCP/21)
・クライアントからサーバへのlsの結果(TCP/20)
で確認すればよいでしょう。

pingを含むICMPというプロトコルは、OSIの7レイヤで言うところのL2(同一セグメント内通信)とL3(IPルーティングされた通信)の両方にまたがる、ちょっと珍しいプロトコルです。

IPアドレスは指定できますが、別サブネットに属するIPアドレスに到達できればL3通信、できなければゲートウェイと呼ばれる同一サブネットに属する中継装置からの回答を得るという点でL2(MAC通信ではなく、同一セグメント内通信という意味)通信です。

ポート番号はL4で使用されるアドレスですから、L4機能の疎通確認はping(を含む...続きを読む


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング