web-dev-qa-db-ja.com

`pushd.`と` cd-`の競合

私はcd -コマンドを使用して前のディレクトリに移動できることを嬉しく思います。同時に、私はpushd .popdが好きです。

ただし、pushd .を使用して現在の作業ディレクトリを記憶したい場合、cd -を使用して前のディレクトリに移動することはできません。 (pushd .cd .も実行するため)。

pushdを使用してcd -を引き続き使用するにはどうすればよいですか。

ちなみに:GNU bash、バージョン4.1.7(1)

5
Bernhard

次のようなものを使用できます。

Push() { 
    if [ "$1" = . ]; then
        old=$OLDPWD
        current=$PWD
        builtin pushd .
        cd "$old"
        cd "$current"
    else
        builtin pushd "$1"
    fi
}

pushdという名前を付けると、関数は組み込みの前に評価されるため、組み込みよりも優先されます。

oldを上書きすると特別な意味が失われるため、変数currentOLDPWDが必要です。

7
Wojtek

Wojtekの答え のもう少し簡潔なバージョン:

pushd () {
        if [ "$1" = . ]; then
                cd -
                builtin pushd -
        else    
                builtin pushd "$1"
        fi      
}

関数にpushdという名前を付けると、通常どおりpushdを使用でき、関数名を使用することを覚えておく必要はありません。

3
Kevin

ケビンの答えは素晴らしいです。問題を解決するためにスクリプトが必要な理由をよりよく理解しようとしている人のために、何が起こっているのかについて詳細を書きました。

pushd .cd -の動作を壊す理由は、cdとディレクトリスタックの動作を掘り下げると明らかになります。いくつかのディレクトリをスタックにプッシュしましょう:

$ mkdir dir1 dir2 dir3
$ pushd dir1
~/dir1 ~
$ pushd../dir2
~/dir2 ~/dir1 ~
$ pushd../dir3
~/dir3 ~/dir2 ~/dir1 ~
$ dirs -v
0       ~/dir3
1       ~/dir2
2       ~/dir1
3       ~

これで、cd -を試してディレクトリに戻ることができます。

$ cd -
/home/username/dir2
$ dirs -v
0       ~/dir2
1       ~/dir2
2       ~/dir1
3       ~

cd -が前のディレクトリにジャンプして戻り、スタック〜0をジャンプしたディレクトリに置き換えていることがわかります。もう一度cd -で戻ることができます。

$ cd -
/home/username/dir3
$ dirs -v
0       ~/dir3
1       ~/dir2
2       ~/dir1
3       ~

前のディレクトリが実際にはディレクトリスタックにリストされていなくても、前のディレクトリに戻ったことに注意してください。これは、cdが環境変数$OLDPWDを使用して、前のディレクトリを追跡しているためです。

$ echo $OLDPWD
/home/username/dir2 

pushd .を実行すると、現在のディレクトリの追加コピーがスタックにプッシュされます。

$ pushd . 
~/dir3 ~/dir3 ~/dir2 ~/dir1 ~
$ dirs -v
0       ~/dir3
1       ~/dir3
2       ~/dir2
3       ~/dir1
4       ~

スタック内の現在のディレクトリの追加コピーを作成することに加えて、pushd .$OLDPWDを更新しました。

$echo $OLDPWD
/home/username/dir3

したがって、cd -はその有用な履歴を失い、現在のディレクトリに移動するだけで、何も実行されません。

0
Spark