Cd için daha fazla geçmişimiz var mı?


Yanıtlar:


31

Aradığınız emir pushdve popd.

Buradanpushd ve buradan pratik çalışan bir örnek popdgörebilirsiniz .

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
$OLDPWDAynı komutu kullanarak iki dizin arasında ileri geri çevirmek istediğinizde de var , ancak bunun kabuğa özgü ve dağıtım / çekirdeğe özgü olduğundan emin değilim.
mechalynx

4
@ivy_lynx OLDPWDtüm POSIX kabuklarda mevcut fakat (soru zaten söz ettiği ötesine nasıl sorar bu soru için yararsız cd -bir kısayol içindir ki cd "$OLDPWD").
Gilles 'SO- kötülük' dur

2
cd /tmp/dir1; pushd . Sadece kullanmak yerine bir sebep var mı pushd /tmp/dir1?
GnP

@gnp, özel bir sebep yok. Cevapta bahsettiğim linkten yeni alınmıştı. pushd /tmp/dir1iyi çalışması gerekir.
Ramesh

1
Tamam, merakımı seçtim. Sana kullanarak gerçek bir örnekle cevap geliştirmek önermek istiyorum pushdve popdileri geri bir dizin ağaçta ilerleme. Cevabınız zaten doğru olanı.
GnP

53

Hangi kabuğu kullandığınızı belirtmediniz, bu yüzden bunun zsh'ın reklamını yapmak için mazeret olmasına izin verin.

Evet, daha geçmişimiz var cdyani cd -2, cd -4vb Çok uygun olduğunu cd -TABözellikle tamamlama sistemi ile ve renkler etkin:

Bu benim .zshrc dediğim şey:

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'

Ve sonuç:

görüntü tanımını buraya girin


4
bash bash bash bash
Tim

7
Tamam, bu cevabı silmeyeceğim, belki başkaları için faydalı olacaktır.
jimmij

23
Soru özellikle sorulmadıkça bash, bu geçerli bir cevaptır. Çıkarma onu.
liori

OP sorusunu yalnızca bash içerecek şekilde düzenlerse, bu cevap hala geçerli olacak mı?
Ooker

3
setopt AUTO_PUSHDBunların dışında, stok zsh içinde tamamlanmış bir omnipresent dizin yığını elde etmek için yukarıdaki kurulumların hiçbirinin gerekli olmadığına değiniyor olabilir. PUSHD_MINUSduygusunu tersine çevirir cd +ve cd -(zevk meselesi), CDABLE_VARSdizin yığınlarıyla alakasızdır ve zstyleburada verilen çağrı , yalnızca bir dizin yığını tamamlamanın çıktısına renklendirici ekler. Ancak, tamamlama alt sistemini ile başlatmak gerekir autoload -U compinit && compinit.
wjv

13

"Daha fazla tarih" ile ilgili sorunuza cevap vermek için. Hayır, cd -Bash'deki özellik yalnızca geri dönebileceğiniz "tek bir dizini" desteklemez. @Ramesh'in cevabında belirtildiği gibi. Eğer dizinleri daha uzun bir geçmişe isterseniz kullanabilirsiniz pushdve popdbir dizin kaydetmek veya bir öncekine dönmek için.

Komutta o anda yığında olanların listesini de görebilirsiniz dirs.

Bu cevaptan ayrıntılı bir açıklama bulunabilir: Pushd ve popd komutlarını nasıl kullanırım? .


Cevabınızdan bir referans ekledim. Umarım sakıncası yoktur. :)
Ramesh

@Ramesh - hayır devam et.
slm

8

Bashe için benim dizin yardımcı programını kurabilir ve kullanabilirsiniz .

Temel olarak, tüm kabuklarınızdaki dizin değişikliklerini toplayan bir servistir ve geçmişi görüntüleyen ve geçmek üzere herhangi bir dizini seçmenize izin veren bir Cdk programıdır (böylece bir yığınla sınırlı kalmazsınız).


7

İstediğiniz kadar geçmişiniz var:

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"
}

Bu, POSIX uyumlu herhangi bir kabuğun zsh-style cdgeçmişini sunmasını sağlayan bir kabuk işlevidir . Tüm çalışmalarını tek bir alt kabuk çağırmadan yapıyor ve akışının oldukça sağlam olduğuna inanıyorum - tüm vakaları orta testler altında doğru bir şekilde ele alıyor gibi görünüyor.

İşlev, tamamen taşınabilir sözdizimine güvenirken, ortamı ile olduğu kadar iyi oynamaya çalışır - yalnızca bir varsayımda bulunur ve bu, $DIRSTACKortam değişkeninin yapacağı gibi onun özelliği olduğu anlamına gelir.

İçerisinde depoladığı tüm yolları kanonize eder $DIRSTACKve hepsini tek tırnak üzerinde sıralar - her birinin değişkenin değerine eklemeden önce güvenli bir şekilde alıntılanmasını ve seri hale getirilmesini sağlar ve herhangi bir özel karakterle ilgili herhangi bir sorunu olmamalıdır. . Eğer $DIRSTACKMAXortam değişkeni ayarlanır o başka sınır biridir, o tarihte korur yolları sayısı için bir üst sınır olarak kullanacaktır.

Eğer fonksiyonu yüklüyorsanız sadece cdnormal ancak aynı zamanda cd -[num]değişiklik dizini geçmişinizi geri almak için for'u da yapabilirsiniz .

İşlevin birincil mekanizması cdkendisidir - ve ${OLD,}PWDortam değişkenleri. POSIX, cdbunların her yol hareketi için değiştirildiğini belirtir - ve bu sadece kabuğun yerleşik değişkenlerini kullanır ve değerleri istediğiniz sürece kaydeder.


@datUser - Birisinin bir dat olduğunu biliyordum. oldukça hoş geldiniz
mikeserv


3

Diğerleri zaten bazı ilginç çözümler ele aldı. Bir süre önce hızlı bir şekilde "düz tarih" yapmak için değiştirilebilecek ilgili bir sorun için kendi çözümümü yarattım. Temelde, sık kullanılan birkaç dizini "etiketlemek" istedim ve tüm açık mermilerin onları görmesini ve yeniden başlatmalar arasında kalmasını istedim .

#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
}

Temelde sadece label fooşu anki dizini foove sonra ne olursa olsun, goto fookimsenin cddoğrudan orada bulunacağını çağırırdım . Boş argüman: labeliçin varsayılan bir hedef oluşturur goto.

Otomatik olarak takma adların otomatik olarak kaldırılmasını zahmet etmedim, ancak aksi halde, bunu hala biraz değiştirilmiş biçimde kullanıyorum.


2

"Cd geçmişi" işlevimi http://fex.belwue.de/fstools/bash.html adresinden kullanabilirsiniz.

Bulunduğunuz her dizini hatırlar ve "cdh" ile son 9 dizinin bir listesini görürsünüz. Sadece numarayı girin ve bu dizine geri dönün.

Örnek:

framstag @ wupp: /: cdh
1: / usr / yerel / kutu
2: / var
3: /
4: / tmp / 135_pana / 1280
5: / tmp / 135_pana
6: / tmp / weihnachtsfeier
7: / tmp
8: / yerel / ev / framstag
seç: 4
framstag @ wupp: / tmp / 135_pana / 1280 ':

cdh, autocd aka "cd'siz cd" ile çalışır: cd veya pushd yazmanıza gerek yoktur.


2

Genişletilmiş 'cd' işlevimi size önermek istiyorum:

https://github.com/dczhu/ltcd

görüntü tanımını buraya girin

Hayatı kolaylaştırmak için aşağıdaki özellikleri sunar:

  • Tüm terminal sekmelerinden / pencerelerinden son ziyaret edilen dizinleri gösteren genel dizin listesi.
  • Geçerli kabuk oturumuna yerel olan yerel dizin listesi.
  • Her iki liste de j / k (aşağı / yukarı), sayılar ve kelime arama özelliğini kullanarak hızlı gezinmeyi destekler.
  • Genel serbest atlama (örn. "Cd dir" veya "cd ar", / path / to / foo / bar / dizin / dizinine gitmek için).

Hm, umut verici görünüyor. Onu ben kontrol edecegim.
ddnomad

1

için bash , temelde: yerine cd kullanımını kullanmanın pushdonlar kaydedilir, böylece değişim directorys için (yığılmış anlam)

pushd /home; pushd /var; pushd log

Yığın kullanımını görmek dirsve daha kolay gezinmek için ("Yığın girişlerinin" sayısını bulmak için:

dirs -v

Çıktı:

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

Şimdi bu sayıları cdve ~benzerleriyle kullanın:

cd ~1

Ancak şimdi bu sayılar şimdi yeniden düzenleniyor ve "0" konumu değişecek, bu nedenle pushddizini iki kez üst konuma getirin (veya 0 konumunda kukla kullanın):

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

şimdi 1..3 orada kalacak pozisyonda bunu bir yerde okudum ama artık bilmiyorum, kredi vermediğim için üzgünüm

(geçerli dizini yığından serbest bırakmak / geçmiş kullanımdan silmek için popd)



1

Sadece fzf işaretlerini olası bir çözüm olarak eklemek istedim .

Kurulduktan sonra, size yer imlerine eklenmiş dizinleri eklemek ve aramak için komutları işaretler ve zıplar (evet, bu tam olarak geçmiş değil, yalnızca kendinize yer verdikleriniz).

Sorun, oturumu belirli bir davranışa karşı koydu / patlattım, yani farklı yığma oturumunda aynı yığına sahip olmak isterdim, yani fzf işaretleri için mümkün.


0

@Mikeserv'in verdiği cevabı denedim, fakat benim için pek işe yaramadı. Nasıl düzelteceğimi bulamadım, bu yüzden kendim yazdım:

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[@]}}")
}

Bu, GitHub Gist olarak da mevcuttur . Bunu kullanmak için, sadece işlevi kendi içine .bashrcveya benzerine yapıştırın; cd -5en son 5. dizine geri dönmek gibi bir şey yapabileceksiniz . cd -hSize tarihçenizi gözden geçireceksiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.