web-dev-qa-db-ja.com

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

現在のディレクトリを自分のプロジェクトディレクトリに変更するための小さなスクリプトを書きます。

#!/bin/bash
cd /home/tree/projects/Java

私は、projのようにこのファイルを保存したchmodと実行権限を追加し、/usr/binするためにそれをコピーしました。それをprojと呼ぶと、何もしません。何がおかしいのですか?

680
ashokgelal

シェルスクリプトはサブシェル内で実行され、各サブシェルには現在のディレクトリとは何かという独自の概念があります。 cdは成功しますが、サブシェルが終了するとすぐに対話型シェルに戻り、そこで何も変更されません。

これを回避する1つの方法は、代わりにエイリアスを使用することです。

alias proj="cd /home/tree/projects/Java"
577
Greg Hewgill

あなたは何も悪いことをしていません!ディレクトリを変更しましたが、スクリプトを実行するサブシェル内でのみです。

現在のプロセスで "dot"コマンドを使ってスクリプトを実行できます。

. proj

しかし、この単純なケースではGregの提案でエイリアスを使用することをお勧めします。

456
Adam Liss

スクリプト内のcdは技術的にはスクリプトを実行するシェルのディレクトリを変更したので働いたですが、それは対話型シェルから分岐した別のプロセスでした。

この問題を解決するためのPosix互換の方法は、シェルが呼び出すコマンドスクリプトではなくシェルプロシージャを定義することです。

jhome () {
  cd /home/tree/projects/Java
}

これを単にタイプするか、またはさまざまなシェルスタートアップファイルの1つに入れることができます。

206
DigitalRoss

cdはスクリプトのシェル内で行われます。スクリプトが終了すると、そのシェルは終了し、その後あなたはあなたがいたディレクトリに残ります。スクリプトを「ソース」にして実行しないでください。の代わりに:

./myscript.sh

行う

. ./myscript.sh

(スクリプト名の前のドットとスペースに注意してください。)

139
Tzachi.e

選択ディレクトリに移動するbashスクリプトを作成するには、以下のようにします。

スクリプトファイルを作成する

#!/ bin/sh 
#ファイル:/scripts/cdjava
#
cd /home/askgelal/projects/Java

その後、スタートアップファイルにエイリアスを作成します。

#!/ bin/sh 
#ファイル/scripts/mastercode.sh
#
alias cdjava = '。 /scripts/cdjava'

  • 私はすべてのエイリアスとカスタム関数をダンプするスタートアップファイルを作成しました。
  • それからこのファイルを私の.bashrcに入れて、ブートごとに設定します。

たとえば、マスターエイリアス/関数ファイルを作成します。 /scripts/mastercode.sh
(このファイルに別名を入れてください。)

それからあなたの終わりに .bashrc ファイル:

 source /scripts/mastercode.sh 



これでJavaディレクトリにcdするのが簡単になりました。cdjavaと入力するだけです。

90
Matt Thomas

シンボリックリンクを使用するというJeremy Rutenの考えは、他の答えと交差しない考えを引き起こしました。つかいます:

CDPATH=:$HOME/projects

先頭のコロンは重要です。つまり、現在のディレクトリにディレクトリ 'dir'があると、他の場所に移動するのではなく、 'cd dir'がそれに変わります。図のように値を設定すると、次のことができます。

cd Java

そして、現在のディレクトリにJavaと呼ばれるサブディレクトリがない場合は、直接$ HOME/projects/Javaに移動します - エイリアス、スクリプト、疑わしいexec、またはドットコマンドは不要です。

私の$ HOMEは/ Users/jlefflerです。私の$ CDPATHは次のとおりです。

:/Users/jleffler:/Users/jleffler/mail:/Users/jleffler/src:/Users/jleffler/src/Perl:/Users/jleffler/src/sqltools:/Users/jleffler/lib:/Users/jleffler/doc:/Users/jleffler/work
36

現在のシェル環境でスクリプトを実行するには、.を使用できます。

. script_name

あるいは、より読みやすいがシェル固有の別名source

source script_name

これはサブシェルを回避し、代わりに現在のシェルに影響を与えるすべての変数または組み込み変数(cdを含む)を許可します。

36
Sagar

. <your file name>を使用してコードを機能させることができました

./<your file name>は端末内のディレクトリを変更しないので機能しません。単にそのスクリプトに固有のディレクトリを変更するだけです。

これが私のプログラムです

#!/bin/bash 
echo "Taking you to Eclipse's workspace."
cd /Developer/Java/workspace

これが私の端末です

nova:~ Kael$ 
nova:~ Kael$ . workspace.sh
Taking you to eclipe's workspace.
nova:workspace Kael$ 
25
kaelhop

最後にexec bashを使う

Bashスクリプトは現在の環境またはその子の環境で動作しますが、親の環境では動作しません。

しかし、この質問は、他のディレクトリからのbashスクリプトの実行後に特定のディレクトリにbash Promptを残すが必要なためによく聞かれます。

この場合、スクリプトの最後に単に子bashインスタンスを実行しますと入力します。

#!/usr/bin/env bash
cd /home/tree/projects/Java
exec bash
21

単に実行します。

cd /home/xxx/yyy && command_you_want
17
warhansen

シェルスクリプトを起動すると、そのシェルの new インスタンスが実行されます(/bin/bash)。したがって、あなたのスクリプトはシェルを起動し、ディレクトリを変更して終了するだけです。別の言い方をすると、シェルスクリプト内のcd(および他のそのようなコマンド)は、それらが起動されたシェルに影響を与えたりアクセスしたりしません。

12
Daniel Spiewak

私の特定のケースでは、私は同じディレクトリに変更するには何度も必要でした。だから私の.bashrc(私はubuntuを使用しています)で私は追加しました

1 -

$ nano〜。/ bashrc

 function switchp
 {
    cd /home/tree/projects/$1
 }

2-

$ source〜/ .bashrc

3 -

$ switchp Java

直接それはするでしょう:cd/home/tree/projects/Java

お役に立てば幸いです。

9
workdreamer

次のことができます。

#!/bin/bash
cd /your/project/directory
# start another Shell and replacing the current
exec /bin/bash

編集:これは、その後のシェルの作成を防ぐために、同様に「点線」にすることができます。

例:

. ./previous_script  (with or without the first line)
9
Thevs

エイリアスとスクリプトを組み合わせることができます。

alias proj="cd \`/usr/bin/proj !*\`"

スクリプトが宛先パスをエコーするという条件で。これらはスクリプト名を囲むバッククォートであることに注意してください。

たとえば、あなたのスクリプトは

#!/bin/bash
echo /home/askgelal/projects/Java/$1

この手法の利点は、スクリプトが任意の数のコマンドラインパラメータを受け取り、複雑なロジックによって計算されたさまざまな出力先を生成できることです。

7
J. A. Faucett

スクリプト自体のディレクトリを変更するだけで、現在のディレクトリは変わりません。

代わりに シンボリックリンク を使用することをお勧めします。それはあなたがファイルまたはディレクトリへの「ショートカット」を作ることを可能にします、それであなたはcd my-projectのような何かをタイプすることだけが必要です。

7
Jeremy Ruten

ディレクトリを素早くナビゲートするには、$ CDPATH、cdargs、およびエイリアスを自動的に生成する方法があります。

http://jackndempsey.blogspot.com/2008/07/cdargs.html

http://muness.blogspot.com/2008/06/lazy-bash-cd-aliaes.html

https://web.archive.org/web/1/http://articles.techrepublic%2ecom%2ecom/5100-10878_11-5827311.html

5
Gene T

Adam&Gregのエイリアスとドットのアプローチを組み合わせて、もっとダイナミックなものにすることができます。

alias project=". project"

プロジェクトエイリアスを実行すると、サブシェルではなく現在のシェルでプロジェクトスクリプトが実行されます。

5
mogga

〜/ .bash_profileファイルにあります。次の機能を追加

move_me() {
    cd ~/path/to/dest
}

端末を再起動すれば、タイプできます

move_me 

あなたは移動先のフォルダに移動します。

3
mihai.ciorobea

実行したいスクリプトを入手することは1つの解決策ですが、このスクリプトは現在のシェルの環境を直接変更できることに注意してください。また、もう引数を渡すことはできません。

もう1つの方法は、スクリプトをbashの関数として実装することです。

function cdbm() {
  cd whereever_you_want_to_go
  echo "Arguments to the functions were $1, $2, ..."
}

このテクニックはautojump: http://github.com/joelthelion/autojump/wiki で使用され、シェルディレクトリのブックマークの学習を提供します。

3
thomasd

これはあなたが望むことをするはずです。 (スクリプト内から)目的のディレクトリに移動し、新しいbashシェルを起動します。

#!/bin/bash

# saved as mov_dir.sh
cd ~/mt/v3/rt_linux-rt-tools/
bash

これを実行すると、目的のディレクトリに移動し、終了すると元の場所に戻ります。

root@intel-corei7-64:~# ./mov_dir.sh

root@intel-corei7-64:~/mt/v3/rt_linux-rt-tools# exit
root@intel-corei7-64:~#

あなたが終了するとき、これはあなたがあなたの元のディレクトリに戻ることさえあなたを連れて行くでしょう(CTRL+d

3
jithu83

&&演算子を使うことができます。

cd myDirectory && ls

3
Jack Bauer

LOOOOOng時間後、しかし私は次のようにしました:

caseという名前のファイルを作成します

以下をファイルに貼り付けます。

#!/bin/sh

cd /home/"$1"

それを保存してから:

chmod +x case

私の.bashrcにもエイリアスを作りました。

alias disk='cd /home/; . case'

今私が入力すると:

case 12345

基本的に私はタイプしています:

cd /home/12345

Caseの後に任意のフォルダを入力できます。

case 12

case 15

case 17

これは入力のようなものです。

cd /home/12

cd /home/15

cd /home/17

それぞれ

私の場合、パスははるかに長くなります - これらの人たちはそれを先に〜情報とまとめました。

2
chris

あなたの.bash_profileに以下のような関数を作成することができ、それはスムーズに機能します。

次の関数はプロジェクトであるオプションのパラメータを取ります。例えば、あなたはただ実行することができます

cdproj

または

cdproj project_name

これが関数の定義です。

cdproj(){
    dir=/Users/yourname/projects
    if [ "$1" ]; then
      cd "${dir}/${1}"
    else
      cd "${dir}"
    fi
}

あなたの.bash_profileを読み忘れてはいけません

2
Krish

スクリプトは不要です。正しいオプションを設定して環境変数を作成するだけです。

shopt -s cdable_vars

あなたの~/.bashrcでは、環境変数の内容をcdにすることができます。

そのような環境変数を作成します。

export myjava="/home/tree/projects/Java"

そしてあなたは使用することができます:

cd myjava

その他の選択肢

0
Gauthier

シェルとして fish を使用している場合、最良の解決策は関数を作成することです。例として、元の質問を考えて、あなたは以下の4行をコピーしてあなたの魚のコマンドラインに貼り付けることができます:

function proj
   cd /home/tree/projects/Java
end
funcsave proj

これにより関数が作成され、後で使用するために保存されます。プロジェクトが変わった場合は、新しいパスを使用してこの手順を繰り返してください。

お望みであれば、次のようにして手動で関数ファイルを追加することができます。

nano ~/.config/fish/functions/proj.fish

そしてテキストを入力してください:

function proj
   cd /home/tree/projects/Java
end

そして最後にctrl + xを押して終了し、yを押して変更を保存します。

注:funcsaveを使用する最初の方法では、proj.fishファイルが自動的に作成されます )。

0
Lane Roathe

ディレクトリの変更を管理するためのpという単純なbashスクリプトがあります。
github.com/godzilla/bash-stuff
スクリプトをローカルのbinディレクトリ(/ usr/local/bin)に置くだけです。
そして、置きます

alias p='. p'

あなたの.bashrcに

0
godzilla

Bashプロファイル関数を使う:

Bashプロファイルの特徴の1つは、アプリケーションまたはコマンドを実行するのと同じ方法で端末またはbashスクリプトで実行できるカスタム関数を格納することです。これは、長いコマンドのショートカットとしても使用できます。

あなたの機能を効率的なシステムにするためには、いくつかのファイルの最後にあなたの機能をコピーする必要があります。

/home/user/.bashrc
/home/user/.bash_profile
/root/.bashrc
/root/.bash_profile

Sudo kwrite /home/user/.bashrc /home/user/.bash_profile /root/.bashrc /root/.bash_profileを使ってこれらのファイルを素早く編集/作成することができます

スクリプト例

cddcd ..へのショートカットを作る

cdd() {
  cd ..
}

lsショートカット

ll() {
  ls -l -h
}

lsショートカット

lll() {
  ls -l -h -a
}

の仕方 :

ファイルの末尾に関数をコピーして端末を再起動すると、cddまたは実行した関数を実行できます。

0
intika

議論に注意してください 親プロセスの作業ディレクトリを設定するにはどうすればいいですか?

それはいくつかのハックな答えを含んでいます。 https://stackoverflow.com/a/2375174/755804 (gdbを介して親プロセスディレクトリを変更します。変更しないでください)および https://stackoverflow.com/a/51985735/755804 (親プロセスの入力ストリームにcd dirnameを挿入するコマンドtailcd。まあ、理想的にはハックではなくbashの一部にするべきです)