Apakah kami memiliki lebih banyak riwayat untuk cd?


Jawaban:


31

Perintah yang Anda cari adalah pushddan popd.

Anda dapat melihat contoh kerja praktis dari pushddan popddari sini .

mkdir /tmp/dir1
mkdir /tmp/dir2
mkdir /tmp/dir3
mkdir /tmp/dir4

cd /tmp/dir1
pushd .

cd /tmp/dir2
pushd .

cd /tmp/dir3
pushd .

cd /tmp/dir4
pushd .

dirs
/tmp/dir4 /tmp/dir4 /tmp/dir3 /tmp/dir2 /tmp/dir1

1
Ada juga $OLDPWDkalau-kalau Anda ingin bolak-balik antara dua direktori menggunakan perintah yang sama, tapi saya tidak yakin bagaimana spesifik shell dan distribusi / kernel-spesifik ini.
mechalynx

4
@ivy_lynx OLDPWDada di semua shell POSIX, tapi tidak ada gunanya untuk pertanyaan ini yang menanyakan bagaimana cara melampauinya (pertanyaan sudah menyebutkan cd -yang merupakan jalan pintas untuk cd "$OLDPWD").
Gilles 'SO- stop being evil'

2
Apakah ada alasan Anda menggunakan cd /tmp/dir1; pushd . bukan hanya pushd /tmp/dir1?
GnP

@gnp, tidak ada alasan khusus. Itu baru saja diambil dari tautan yang saya sebutkan dalam jawaban. pushd /tmp/dir1harus bekerja dengan baik.
Ramesh

1
Ok, baru saja pilih rasa penasaran saya. Saya ingin menyarankan Anda meningkatkan jawaban Anda dengan contoh aktual menggunakan pushddan popduntuk melintasi pohon direktori bolak-balik. Jawaban Anda sudah benar.
GnP

54

Anda tidak menentukan shell mana yang Anda gunakan, jadi biarkan ini menjadi alasan untuk beriklan zsh.

Ya, kami memiliki lebih banyak riwayat cd, yaitu cd -2, cd -4dll. Sangat mudah cd -TAB, terutama dengan sistem penyelesaian dan warna yang diaktifkan:

Ini yang saya miliki di .zshrc:

setopt AUTO_PUSHD                  # pushes the old directory onto the stack
setopt PUSHD_MINUS                 # exchange the meanings of '+' and '-'
setopt CDABLE_VARS                 # expand the expression (allows 'cd -2/tmp')
autoload -U compinit && compinit   # load + start completion
zstyle ':completion:*:directory-stack' list-colors '=(#b) #([0-9]#)*( *)==95=38;5;12'

Dan hasilnya:

masukkan deskripsi gambar di sini


4
bash bash bash bash
Tim

7
Oke, saya tidak akan menghapus jawaban ini, mungkin akan bermanfaat bagi orang lain.
jimmij

23
Kecuali pertanyaan yang diajukan secara spesifik bash, ini adalah jawaban yang valid. Jangan hapus itu.
liori

Bagaimana jika OP mengedit pertanyaannya untuk memasukkan bash saja, apakah jawaban ini masih valid?
Ooker

3
Mungkin perlu disebutkan bahwa selain dari setopt AUTO_PUSHD, tidak ada pengaturan di atas diperlukan untuk mendapatkan tumpukan direktori yang ada di mana-mana dengan penyelesaian di zsh saham. PUSHD_MINUSmembalikkan indera cd +dan cd -(masalah selera), CDABLE_VARStidak relevan dengan tumpukan direktori, dan zstylepermohonan yang diberikan di sini hanya menambah pewarnaan pada output penyelesaian tumpukan direktori. Namun seseorang harus menginisialisasi subsistem penyelesaian autoload -U compinit && compinit.
wjv

13

Untuk menjawab pertanyaan Anda tentang "lebih banyak sejarah". Tidak ada cd -fitur di Bash yang hanya mendukung satu direktori yang dapat Anda "balikkan" ke belakang. Seperti @Ramesh menyatakan dalam jawabannya. Jika Anda menginginkan riwayat direktori yang lebih panjang, Anda dapat menggunakan pushddan popdmenyimpan direktori atau kembali ke direktori sebelumnya.

Anda juga dapat melihat daftar apa yang saat ini ada di tumpukan dengan dirsperintah.

Penjelasan terperinci dapat ditemukan dari jawaban ini berjudul: Bagaimana cara saya menggunakan perintah pushd dan popd? .


Saya telah memasukkan referensi dari jawaban Anda. Semoga kamu tidak keberatan. :)
Ramesh

@ Ramesh - tidak usah maju.
slm

8

Anda dapat menginstal dan menggunakan utilitas dirhistory saya untuk bash.

Pada dasarnya, ini adalah daemon yang mengumpulkan perubahan direktori dari semua shell Anda, dan program Cdk yang menampilkan histori dan memungkinkan Anda memilih direktori mana saja untuk beralih (sehingga Anda tidak terbatas pada tumpukan).


7

Anda memiliki riwayat sebanyak yang Anda inginkan:

cd() {
[ "$((${DIRSTACKMAX##*[!0-9]*}0/10))" -gt 0 ] &&
        set -- "$@" "$DIRSTACK"               &&
        DIRSTACK='pwd -P >&3; command cd'     ||
        { command cd "$@"; return; }
_q()    while   case "$1" in (*\'*) :   ;;      (*)
                ! DIRSTACK="$DIRSTACK '$2$1'"   ;;esac
        do      set -- "${1#*\'}" "$2${1%%\'*}'\''"
        done
while   [ "$#" -gt 1 ]
do      case    ${1:---} in (-|[!-]*|-*[!0-9]*) : ;;
        (*)     eval "  set $((${1#-}+1))"' "${'"$#}\""
                eval '  set -- "$2"'" $2"'
                        set -- "${'"$1"'}" "$1"'
        ;;esac; _q "$1"; shift
done
eval "  DIRSTACK=; $DIRSTACK    &&"'
        _q "$OLDPWD"            &&
        DIRSTACK=$DIRSTACK\ $1
        set "$?" "${DIRSTACK:=$1}"'" $1
"       3>/dev/null
[ "$(($#-1))" -gt "$DIRSTACKMAX" ] &&
        DIRSTACK="${DIRSTACK% \'/*}"
unset -f _q; return "$1"
}

Itu adalah fungsi shell yang harus mengaktifkan setiap shell kompatibel POSIX untuk menawarkan zsh-style style cd. Itu melakukan semua pekerjaannya tanpa menggunakan satu subkulit tunggal, dan saya percaya alirannya cukup baik - tampaknya menangani semua kasus dengan benar di bawah pengujian moderat.

Fungsi ini mencoba untuk bermain sebaik dengan lingkungannya karena mungkin sambil tetap bergantung pada sintaks yang sepenuhnya portabel - ia hanya membuat satu asumsi dan itu adalah bahwa $DIRSTACKvariabel lingkungan adalah properti yang harus dilakukan sesuai dengan keinginannya.

Itu meng-kanoniskan semua jalur yang disimpannya $DIRSTACKdan membuat serialisasi semuanya pada tanda kutip tunggal - meskipun itu memastikan masing-masing dengan aman dikutip dan diserialisasi sebelum menambahkannya ke nilai variabel dan tidak boleh memiliki masalah dengan karakter khusus apa pun dalam bentuk apa pun . Jika $DIRSTACKMAXvariabel lingkungan disetel, variabel itu akan menggunakannya sebagai batas atas untuk jumlah lintasan yang disimpan dalam riwayat, jika tidak maka batasannya adalah satu.

Jika Anda memuat fungsi Anda cdseperti biasa tetapi juga akan dapat melakukan cd -[num]untuk menelusuri kembali melalui direktori perubahan perubahan Anda.

Mekanisme utama fungsi itu cdsendiri - dan ${OLD,}PWDvariabel lingkungan. POSIX menentukan bahwa cdubah ini untuk setiap perpindahan jalur - dan ini hanya menggunakan variabel bawaan shell dan menyimpan nilai selama yang Anda inginkan.


@datUser - saya tahu seseorang memiliki data. youre cukup menyambut
mikeserv


3

Yang lain sudah membahas beberapa solusi menarik. Beberapa waktu lalu saya membuat solusi saya sendiri untuk masalah terkait yang dapat dengan cepat dimodifikasi untuk melakukan "sejarah lurus". Saya pada dasarnya ingin "memberi label" pada beberapa direktori yang umum digunakan, dan ingin semua shell terbuka untuk melihatnya, dan agar mereka tetap ada di antara reboot.

#dir_labels
#functions to load and retrieve list of dir aliases

function goto_complete {
    unset dir_labels
    declare -A dir_labels
    {
    while read line; do
        ll_pre="${line%% *}"
        ll_dir="${line#* }"
        dir_labels["$ll_pre"]="$ll_dir"
    done
    } < ~/.dir_labels
    unset ll_pre
    unset ll_dir

    local cur possib
    cur="${COMP_WORDS[COMP_CWORD]}"
    possib="${!dir_labels[@]}"
    COMPREPLY=( $(compgen -W "${possib}" -- ${cur}) )
}

complete -F goto_complete goto

function goto {
    unset dir_labels
    declare -A dir_labels
    {
    while read line; do
        ll_pre="${line%% *}"
        ll_dir="${line#* }"
        dir_labels["$ll_pre"]="$ll_dir"
    done
    } < ~/.dir_labels
    unset ll_pre
    unset ll_dir

    if [ $# -gt 0 ]; then
    key="$1"
    else
    key=default
    fi
    target="${dir_labels[$key]}"
    if [ -d "$target" ]; then
    cd "$target"
    echo "goto $key: '$target'"
    else
    echo "directory '$target' does not exist"
    fi
}

function label {
    unset dir_labels
    declare -A dir_labels
    {
    while read line; do
        ll_pre="${line%% *}"
        ll_dir="${line#* }"
        dir_labels["$ll_pre"]="$ll_dir"
    done
    } < ~/.dir_labels
    unset ll_pre
    unset ll_dir

    if [ $# -gt 0 ]; then
    target="$1"
    else
    target="default"
    fi
    dir_labels["$target"]=$PWD
    for i in "${!dir_labels[@]}"; do
    echo "$i ${dir_labels[$i]}"
    done > ~/.dir_labels
}

Pada dasarnya saya hanya akan melakukan label foomemanggil direktori saat ini foo, dan kemudian dari apa pun shell, goto foowhould cdlangsung di sana. Argumen kosong: labelakan membuat target default untuk goto.

Saya tidak repot-repot menerapkan penghapusan alias secara otomatis, tetapi jika tidak, saya masih menggunakan ini dalam bentuk yang sedikit dimodifikasi.


2

Anda dapat menggunakan fungsi "cd history" saya dari http://fex.belwue.de/fstools/bash.html

Ia mengingat setiap direktori di mana Anda berada dan dengan "cdh" Anda akan melihat daftar 9 direktori terakhir. Cukup masukkan nomornya dan Anda kembali ke direktori ini.

Contoh:

framstag @ wupp: /: cdh
1: / usr / local / bin
2: / var
3: /
4: / tmp / 135_pana / 1280
5: / tmp / 135_pana
6: / tmp / weihnachtsfeier
7: / tmp
8: / local / home / framstag
pilih: 4
framstag @ wupp: / tmp / 135_pana / 1280:

cdh bekerja dengan autocd alias "cd without cd": Anda tidak perlu mengetik cd atau pushd.


2

Saya ingin merekomendasikan fungsi 'cd' saya yang diperluas kepada Anda:

https://github.com/dczhu/ltcd

masukkan deskripsi gambar di sini

Ini menyediakan fitur berikut untuk membuat hidup lebih mudah:

  • Daftar direktori global, yang menunjukkan direktori terakhir yang dikunjungi dari semua tab / jendela terminal.
  • Daftar direktori lokal, yang merupakan sesi shell lokal saat ini.
  • Kedua daftar mendukung navigasi cepat dengan menggunakan j / k (turun / naik), angka, dan pencarian kata.
  • Global free jumping (mis. "Cd dir" atau "cd ar" untuk menuju ke / path / ke / foo / bar / direktori /).

Hm, terlihat menjanjikan. Saya akan mengeceknya.
ddnomad

1

untuk bash , pada dasarnya: alih-alih menggunakan cd gunakan pushduntuk mengubah direktori, jadi mereka disimpan (artinya ditumpuk)

pushd /home; pushd /var; pushd log

Untuk melihat penggunaan tumpukan dirsdan untuk navigasi yang lebih mudah (untuk mendapatkan nomor "entri-tumpukan" gunakan:

dirs -v

Keluaran:

me@myhost:/home$ dirs -v
 0  /home
 1  /var
 2  /tmp

Sekarang gunakan angka-angka ini dengan cddan ~suka:

cd ~1

Tetapi sekarang angka-angka ini disusun kembali sekarang dan posisi "0" akan berubah, jadi hanya pushddirektori ke posisi teratas dua kali (atau gunakan dummy di posisi 0) seperti:

me@myhost:/home$ dirs -v
 0  /home
 1  /home
 2  /var
 3  /tmp

sekarang 1..3 akan tetap di sana posisi saya membaca ini di suatu tempat tetapi tidak tahu lagi, jadi maaf karena tidak memberikan kredit

(untuk melepaskan direktori saat ini dari tumpukan / menghapusnya dari penggunaan sejarah popd)


1

Lihat fungsi cdh di "Shell Programming, 4e" di halaman 312. Itu menyimpan sejarah dalam array.

Ini versi yang lebih canggih: https://drive.google.com/open?id=0B4f-lR6inxQWQ1pPZVpUQ3FSZ2M

Ini Menyimpan sejarah dalam file CDHISTFILE dan memungkinkan perubahan ke direktori terbaru yang berisi string, misalnya,

cd -src

Itu menginstal sendiri atas perintah cd yang ada dengan melakukan alias cd=_cd


1

Hanya ingin menambahkan fzf-mark sebagai solusi yang memungkinkan.

Setelah diinstal itu memberi Anda tanda perintah dan melompat untuk menambah dan mencari direktori yang ditandai (ya, itu bukan riwayat lengkap, hanya yang Anda bookmark sendiri).

Masalah yang saya miliki dengan perilaku khusus sesi pushd / popd itu, yaitu saya ingin memiliki tumpukan yang sama pada sesi bash yang berbeda atau lebih yang mungkin untuk tanda fzf.


0

Saya mencoba jawaban yang diberikan @mikeserv, tetapi tidak berhasil bagi saya. Saya tidak tahu cara memperbaikinya, jadi saya hanya menulis sendiri:

cd() {
    # Set the current directory to the 0th history item
    cd_history[0]=$PWD
    if [[ $1 == -h ]]; then
        for i in ${!cd_history[@]}; do
            echo $i: "${cd_history[$i]}"
        done
        return
    elif [[ $1 =~ ^-[0-9]+ ]]; then
        builtin cd "${cd_history[${1//-}]}" || # Remove the argument's dash
        return 
    else
        builtin cd "$@" || return # Bail if cd fails
    fi
    # cd_history = ["", $OLDPWD, cd_history[1:]]
    cd_history=("" "$OLDPWD" "${cd_history[@]:1:${#cd_history[@]}}")
}

Ini juga tersedia sebagai GitHub Gist . Untuk menggunakan ini, hanya menyisipkan fungsi ke dalam .bashrcatau serupa, dan Anda akan dapat melakukan hal-hal seperti cd -5untuk kembali ke 5 th direktori terakhir Anda sudah berada di. cd -hAkan memberikan gambaran tentang sejarah Anda.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.