web-dev-qa-db-ja.com

シェルスクリプトで「cd」が機能しないのはなぜですか?

ディレクトリを変更するのスクリプトを書きたいだけです。

次のコマンドをファイルに入れます/home/alex/pathABC

#!/bin/sh
cd /home/alex/Documents/A/B/C
echo HelloWorld

私はchmod +x pathABCをしました。

ターミナルでは、/home/alex./pathABCを実行しますが、出力はHelloWorldであり、現在のディレクトリは変更されません。

それで何が悪いのでしょうか?

42

他の人が説明したように、ディレクトリは、スクリプトの呼び出し元のターミナルプロセスではなく、スクリプトの子プロセスで変更されます。子プロセスが終了すると、元の場所に残っているターミナルに戻ります。

いくつかの選択肢:

1。シンボリックリンク

簡単にアクセスしたい長いパスへのシンボリックリンクを家に置きます

$ ln -s /home/alex/Documents/A/B/C ~/pathABC

次に、ディレクトリにアクセスします。

$ cd ~/pathABC

2。エイリアス

〜/ .bashrcにエイリアスを置きます:

alias pathABC="cd /home/alex/Documents/A/B/C"

(from here

3。関数

ディレクトリを変更する関数を作成します。関数は端末のプロセスで実行され、ディレクトリを変更できます。

(from here

4。子として実行しないでください

スクリプトを実行する代わりにソースします。ソーシング(.またはsourceによって行われます)は、独自のサブシェルで実行するのではなく、同じシェルでスクリプトを実行します。

$ . ./pathABC

here および here から)

5。 cd-able vars

cdable_vars~/.bashrcオプションを設定し、ディレクトリに環境変数を作成します。

shopt -s cdable_vars
export pathABC="/home/alex/Documents/A/B/C"

その後、cd pathABCを使用できます

(from here

72
Gauthier

ターミナルでスクリプトを実行すると、子プロセスが実行されます。この子プログラムでは、スクリプトは指定されたディレクトリに変更されます。ただし、親プロセス、つまりスクリプトを実行する場所では、まだ古いパスにあります。 OR簡単に言うことができます:

The scope of cd command is only for child process not parent

7
Tingrammer

あなたは思考エラーを犯しています。現在のShellは同じディレクトリにありますが、scriptは新しいディレクトリに移動しました。

newディレクトリに別のスクリプトを作成し、ディレクトリを変更した後、スクリプトから実行することで、それを確認できます。

#!/bin/sh
cd /home/alex/Documents/A/B/C && ./another_script.sh # (if it is executable)

2番目のスクリプトは、新しいディレクトリから実行されます。

HelloWorld 

スクリプトの単なる出力です。

4
Jacob Vlijm

Hello Worldは単なるトレースステートメントであるため、これを試してみましょう。

次を含むbashスクリプトファイルcd.shを作成します。

#!/bin/bash
echo "/home/mike/Documents/A/B/C"
  • .sh拡張子は、bashスクリプトのファイル名に拡張子を付ける古い規則です。それは純粋に化粧品であり、通常は不要です。ただし、この場合、コアcdコマンドと区別することが重要です。

次を使用して、bashスクリプトファイルを実行可能としてマークします。

chmod a+x cd.sh

ファイルを実行します:

$ cd $(./cd.sh)
bash: cd: /home/alex/Documents/A/B/C: No such file or directory
  • cd私たちは皆知っています。
  • $(...)は、括弧内でコマンドを実行し、出力を返します。
  • cd.shがパスにあった場合、それがどこにあるかを指定する必要はありません。コマンドが現在のディレクトリにあることを指定するために、./というプレフィックスを付けます。
  • cd.shスクリプトからのecho出力は、$(...)を介して親に返送されます。親(シェルプロンプト)はこの出力を使用し、Linux cdコマンドに渡します。

他の人が言及したように、子プロセスは親のディレクトリを変更できません。これは、プロセスが終了した後、子が親にどこに行くべきかを伝えることができる1つの方法です。

0