現在のディレクトリを変更するスクリプト(cd、pwd)


回答:


63

これは予想される動作であり、すでに何度か議論されています。

スクリプトはサブシェルで実行され、親シェルの作業ディレクトリを変更できません。終了すると、その効果は失われます。

ディレクトリを永続的に変更するには、次のようにスクリプトをソースする必要があります

. ./script

8
@Sony:returnこの方法でソースされたスクリプトからエスケープするために使用する必要があることに注意してくださいexit-これらはシェル関数のようでありexit、スクリプトをソースしたシェルを終了します。
チャールズスチュワート

@CharlesStewart実際、私はソーススクリプトに精通していません。ありがとうございました!
ソニーサントス

5
あるsource ./script同じ?
アミアシン

2
@amyassin:はい、そうです
enzotib

2
1. .およびsourcebashが等しい。2. ./同じディレクトリにある場合、ファイル名の前に使用する必要はありません。:これだけで実行しても大丈夫です. script
sobi3ch

19

このような小さなタスクの場合、スクリプトを作成する代わりに、このようなエイリアスを作成し、

$ alias cdproj='cd /dir/web/www/proj'

.bashrcすべての対話型シェルに設定する場合は、これをファイルに追加する必要があります。

これで、これをとして実行できます$ cdproj


1
また、スクリプトに実行するコマンドをエコーさせてから、eval `./script` またはeval $(./script)を使用してそれらのコマンドを実行することもできます。これは、呼び出しシェルの環境を更新する必要があるコマンドの一般的なアプローチです。
キーストンプソン

2
evalアプローチを行う場合は、出力する内容に注意してください。
-jw013

13

exec bash最後に使用

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

ただし、別のディレクトリからbashスクリプトを実行した後、特定のディレクトリのbashプロンプトのままにしておきたいため、この質問がよく聞かれます

この場合、スクリプトの最後で子bashインスタンスを実行するだけです:

#!/usr/bin/env bash
cd desired/directory
exec bash

これにより、新しいサブシェルが作成されます。入力exitして、スクリプトが最初に開始された最初のシェルに戻ります。


ただソースへのより良い受け入れ答えのようにスクリプト:使用してexec一般的に悪党の最後の手段と考えられます。.. :)
ニューロ

1
このトリックは、Debian 9ストレッチでは機能しません。
vdegenne

3
これはこれについて間違った方法です!
デニスウィリアムソン

3
誰もこれに関する問題を詳しく述べていないので(@Dennisを探しています):(1)これを実行するたびに、新しい永続的なbashプロセスが作成されます。1回のセッションで10〜20回実行すると、11〜21のbashプロセスが積み重ねられます。これはパフォーマンスに影響する可能性があり、入力exit(またはCtrl + D)によってセッションを正常に終了しようとすると、11〜21 回実行する必要があります。(2)実行可能スクリプトを使用する別の欠点は、インタラクティブシェルセッションでシェルオプション(  dotglobまたは  globstar)を設定すると、新しいシェルを開始するため、それらが失われることです。
G-Manが「Reinstate Monica」と言う

1
非常に素晴らしい解決策!bash_profileのエイリアスを書き換えたので、別のファイルに保存されたスクリプトになりました。スクリプトを使用して、新しく作成された一時フォルダーに移動します。そして今では、一時的なbashセッションを持つのがさらに簡単になりました。動作中のSRP!ありがとう!
artyom.razinov

8

あなたが望む正確なアクションを行う答えがありますが、そのような目的のためのより標準的な方法はシンボリックリンクを作成することです:

ln -s ~/web/www/project proj   #use full path to dir!

次にcd、名前を使用してディレクトリに移動できますproj

cd proj

この方法は、次のようにせずに短い名前を使用してファイルにアクセスできるため、より柔軟ですcd

ls proj/   #note the endslash!
vim proj/file.x


4

実行する内容に応じて、スクリプトではなく関数を作成することもできます。

例:

ファイルに関数を作成します/home/aidin/my-cd-script

function my-cd() {
  cd /to/my/path
}

次に、それをあなたのbashrcor zshrcファイルに含めます:

# Somewhere in rc file
source /home/aidin/my-cd-script

これでコマンドのように使用できます:

$ my-cd

0

「exec」を使用して、私が望んでいることを正確に実行するのはなぜですか。

#!/bin/bash

cd someplace
exec bash

~/someplace

1
あなたが望むものと思われるものに注意してください。(巨大な木製の馬!私が欲しかったもの!)これを実行するたびに、新しい永続的なbashプロセスが作成されます。1回のセッションで10〜20回実行すると、11〜21のbashプロセスが積み重ねられます。これはパフォーマンスに影響する可能性があり、入力exit(またはCtrl + D)によってセッションを正常に終了しようとすると、11〜21 回実行する必要があります。
G-Manによると、「Reinstate Monica」

どこが問題になるかは間違いなくわかりました。私にとっては、一度使用して、必要な作業をしてから終了しますが、それが唯一の欠点であれば、それで生きることができます。一方、より良い解決策があれば、喜んでそれを見ていきます。
ポール

シェル関数を使用したこの質問に対するAidinの回答と、エイリアスを使用したSachin Divekarの回答は、スクリプトを使用するよりも(IMO)優れたソリューションです。PSスクリプトを使用するもう1つの欠点は、シェルオプション(  dotglobまたはなど  globstar)を設定すると、新しいシェルを開始するためにそれらが失われることです。…(続き)
G-Manが「Reinstate Monica」と言う

(続き)... PPS私は繰り返し強調、基本的に、あなたがしていることに気づいセルジュStroobandtの答えをと「言って」これをしないのはなぜ?「」で  スタック交換我々は新しいアイデアおよび/または情報を提供するために、答えを期待する、とだけで議論していません他の答え。
G-Manによると、「Reinstate Monica」

-1

関数または&&を使用してそれを行うことができます。以下の例では、Zabbixをインストールし、その中に1行のファイルを作成します。

例:

#!/bin/bash

# Create Function:
installZabbix(){
    cd /usr/src/zabbix-4.2.4;
    ./configure --enable-agent;
    make install;
    cd /usr/src/;
    >file;
    echo "Hi, this is a file." >>file;
}

# Call the function:
installZabbix

または:

#!/bin/bash
cd /usr/src/zabbix-4.2.4 && ./configure --enable-agent && make install && cd /usr/src && >file && echo "Hi, this is a file." >>file
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.