เรามีประวัติเพิ่มเติมสำหรับ cd หรือไม่?


42

cd -สามารถย้ายไปยังไดเรกทอรีที่เยี่ยมชมล่าสุด เราสามารถเยี่ยมชมประวัติศาสตร์อื่น ๆ นอกเหนือจากที่ผ่านมาได้หรือไม่


คำตอบ:


31

คำสั่งที่คุณกำลังมองหาและpushdpopd

คุณสามารถดูตัวอย่างการทำงานในทางปฏิบัติของpushdและpopdจากที่นี่

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
นอกจากนี้ยังมี$OLDPWDในกรณีที่คุณต้องการพลิกไปมาระหว่างสองไดเรกทอรีโดยใช้คำสั่งเดียวกัน แต่ฉันไม่แน่ใจว่าเชลล์เฉพาะและการกระจาย / เคอร์เนลเฉพาะนี้เป็นอย่างไร
mechalynx

4
@ivy_lynx OLDPWDมีอยู่ในเชลล์ POSIX ทั้งหมด แต่มันไร้ประโยชน์สำหรับคำถามนี้ซึ่งถามว่าจะทำอะไรได้มากกว่านั้น (คำถามนี้พูดถึงแล้วcd -ซึ่งเป็นทางลัดสำหรับcd "$OLDPWD")
Gilles 'หยุดชั่วร้าย'

2
มีเหตุผลที่คุณใช้cd /tmp/dir1; pushd . แทนที่จะเป็นเพียงแค่pushd /tmp/dir1?
GnP

@gnp ไม่มีเหตุผลเฉพาะ มันเพิ่งมาจากลิงค์ที่ฉันได้อ้างถึงในคำตอบ pushd /tmp/dir1ควรทำงานได้ดี
Ramesh

1
ตกลงเพียงแค่เลือกความอยากรู้ของฉัน ฉันอยากจะแนะนำให้คุณปรับปรุงคำตอบของคุณด้วยตัวอย่างจริงโดยใช้pushdและpopdสำรวจแผนผังไดเรกทอรีกลับไปกลับมา คำตอบของคุณนั้นถูกต้องแล้ว
GnP

53

คุณไม่ได้ระบุว่าคุณใช้เชลล์ตัวไหนเป็นข้ออ้างในการโฆษณา zsh

ใช่เราทำมีประวัติมากขึ้นสำหรับการcdคือcd -2, cd -4ฯลฯ มากสะดวกสบายcd -TABโดยเฉพาะอย่างยิ่งกับระบบเสร็จและเปิดใช้งานสี:

นี่คือสิ่งที่ฉันมีใน. 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'

และผลลัพธ์:

ป้อนคำอธิบายรูปภาพที่นี่


4
ทุบตีทุบตีทุบตีทุบตี
ทิม

7
ตกลงฉันจะไม่ลบคำตอบนี้อาจจะเป็นประโยชน์สำหรับผู้อื่น
jimmij

23
bashนี่เป็นคำตอบที่ถูกต้องหากไม่มีคำถามที่ถามโดยเฉพาะ อย่าลบมัน
liori

จะเกิดอะไรขึ้นถ้า OP แก้ไขคำถามของเขาให้รวมเฉพาะ bash เท่านั้นคำตอบนี้จะใช้ได้หรือไม่
Ooker

3
อาจมีการกล่าวถึงว่านอกเหนือจากsetopt AUTO_PUSHDการตั้งค่าข้างต้นไม่จำเป็นต้องได้รับไดเรกทอรีไดเรกทอรีอยู่ทั่วไปทุกหนทุกแห่งด้วยความสมบูรณ์ในสต็อก zsh PUSHD_MINUSฝืนความรู้สึกของcd +และcd -(เรื่องของรสนิยม) CDABLE_VARSไม่เกี่ยวข้องกับไดเรกทอรีกองและการzstyleภาวนาที่ได้รับที่นี่เพียงแค่เพิ่มสีให้กับการส่งออกของไดเรกทอรีสแต็คเสร็จ แต่หนึ่งต้อง initialise autoload -U compinit && compinitระบบย่อยเสร็จสิ้นด้วย
wjv

13

หากต้องการตอบคำถามของคุณเกี่ยวกับ "ประวัติเพิ่มเติม" ไม่มีcd -คุณสมบัติใน Bash เพียงรองรับไดเรกทอรีเดียวที่คุณสามารถ "พลิก" กลับไป ในฐานะ @Ramesh ระบุไว้ในคำตอบของเขา หากคุณต้องการประวัติไดเรกทอรีที่ยาวขึ้นคุณสามารถใช้pushdและpopdบันทึกไดเรกทอรีหรือกลับไปยังไดเรกทอรีก่อนหน้า

คุณยังสามารถดูรายการสิ่งที่อยู่ในสแต็กด้วยdirsคำสั่ง

คำอธิบายโดยละเอียดสามารถพบได้จากคำตอบนี้ชื่อ: ฉันจะใช้คำสั่ง pushd และ popd ได้อย่างไร .


ฉันได้รวมการอ้างอิงจากคำตอบของคุณ หวังว่าคุณจะไม่รังเกียจ :)
Ramesh

@Ramesh - ไม่ไปข้างหน้า
slm

8

คุณสามารถติดตั้งและใช้ยูทิลิตี้dirhistoryของฉันสำหรับทุบตี

โดยทั่วไปแล้วมันเป็นดีมอนที่รวบรวมการเปลี่ยนแปลงไดเรกทอรีจากเชลล์ทั้งหมดของคุณและโปรแกรม Cdk ที่แสดงประวัติและให้คุณเลือกไดเรกทอรีใด ๆ เพื่อสลับไปที่ (ดังนั้นคุณไม่ได้ จำกัด อยู่ที่สแต็ก)


7

คุณมีประวัติมากที่สุดเท่าที่คุณต้องการ:

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

นั่นคือฟังก์ชั่นเชลล์ที่ควรเปิดใช้งานเชลล์ที่ทำงานร่วมกันได้ของ POSIX เพื่อเสนอประวัติzshสไตล์ cdมันทำงานได้ทั้งหมดโดยไม่ต้องเรียกใช้ subshell เดียวและฉันเชื่อว่าการไหลของเสียงค่อนข้างดี - ดูเหมือนว่าจะจัดการกับทุกกรณีได้อย่างถูกต้องภายใต้การทดสอบระดับปานกลาง

ฟังก์ชั่นพยายามที่จะเล่นเป็นอย่างดีกับสภาพแวดล้อมของมันในขณะที่ยังคงพึ่งพาไวยากรณ์แบบพกพาอย่างเต็มที่ - มันทำให้สมมติฐานเดียวเท่านั้นและนั่นคือ$DIRSTACKตัวแปรสภาพแวดล้อมเป็นคุณสมบัติที่จะทำตามที่มันจะ

มันเป็นที่ยอมรับทุกเส้นทางที่มันเก็บไว้$DIRSTACKและทำให้เป็นอนุกรมทั้งหมดของพวกเขาในราคาเดียว - แม้ว่ามันจะทำให้แน่ใจว่าแต่ละคนจะถูกยกมาอย่างปลอดภัยและต่อเนื่องก่อนที่จะเพิ่มลงในค่าของตัวแปรและไม่ควรมีปัญหาใด ๆ กับอักขระพิเศษใด ๆ . หาก$DIRSTACKMAXมีการตั้งค่าตัวแปรสภาพแวดล้อมมันจะใช้เป็นขีด จำกัด สูงสุดสำหรับจำนวนเส้นทางที่เก็บไว้ในประวัติศาสตร์มิฉะนั้นขีด จำกัด คือหนึ่ง

หากคุณโหลดฟังก์ชั่นที่คุณทำcdตามปกติ แต่จะสามารถทำการcd -[num]ย้อนกลับไปยังประวัติไดเรกทอรีการเปลี่ยนแปลงของคุณได้

กลไกหลักของฟังก์ชั่นคือcdตัวเอง - และ${OLD,}PWDตัวแปรสภาพแวดล้อม POSIX ระบุว่าcdการเปลี่ยนแปลงเหล่านี้สำหรับทุกการย้ายพา ธ - ดังนั้นนี่จึงใช้ตัวแปรบิวอินของเชลล์และบันทึกค่าตราบเท่าที่คุณต้องการ


@datUser - ฉันรู้ว่ามีคนที่มีข้อมูล คุณค่อนข้างยินดีต้อนรับ
mikeserv

4

acd_func.shสคริปต์ไม่ตรงกับสิ่งที่คุณอธิบาย เป็นหลักมันเกินcdฟังก์ชั่นและช่วยให้คุณสามารถพิมพ์cd --เพื่อรับรายชื่อของไดเรกทอรีที่เข้าชมก่อนหน้านี้ซึ่งคุณสามารถเลือกตามจำนวน ฉันพบว่ามันยากมากที่จะใช้ bash โดยปราศจากสิ่งนี้อีกต่อไปและสิ่งแรกที่ฉันติดตั้งในระบบใหม่



3

คนอื่น ๆ ได้กล่าวถึงวิธีแก้ปัญหาที่น่าสนใจอยู่แล้ว บางครั้งที่ผ่านมาฉันได้สร้างวิธีการแก้ปัญหาของตัวเองไปยังปัญหาที่เกี่ยวข้องที่สามารถแก้ไขได้อย่างรวดเร็วเพื่อทำ "ประวัติศาสตร์ตรง" โดยทั่วไปฉันต้องการที่จะ "ติดป้าย" ไดเรกทอรีที่ใช้กันทั่วไปและต้องการเปลือกที่เปิดอยู่ทั้งหมดเพื่อดูพวกเขาและเพื่อให้พวกเขายังคงอยู่ระหว่างการรีบูต

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

โดยทั่วไปฉันต้องการเพียงแค่ทำlabel fooเพื่อเรียกไดเรกทอรีปัจจุบันfooและจากสิ่งที่เปลือกgoto fooWhould cdโดยตรงมี อาร์กิวเมนต์ที่ว่างเปล่าจะสร้างเป้าหมายเริ่มต้นสำหรับlabelgoto

ฉันไม่ได้กังวลกับการลบชื่อแทนอัตโนมัติ แต่อย่างอื่นฉันยังคงใช้มันในรูปแบบที่ปรับเปลี่ยนเล็กน้อย


2

คุณสามารถใช้ฟังก์ชั่น "cd history" ของฉันได้จาก http://fex.belwue.de/fstools/bash.html

มันจะจำทุก ๆ ไดเรกทอรีที่คุณเคยอยู่และด้วย "cdh" คุณจะเห็นรายการของ 9 ไดเรกทอรีล่าสุด เพียงแค่ใส่หมายเลขและคุณจะกลับมาในไดเรกทอรีนี้

ตัวอย่าง:

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
เลือก: 4
framstag @ wupp: / tmp / 135_pana / 1280:

cdh ทำงานกับ autocd หรือที่รู้จักว่า "cd without cd": คุณไม่จำเป็นต้องพิมพ์ cd หรือ pushd


2

ฉันอยากจะแนะนำฟังก์ชั่น 'cd' เพิ่มเติมให้กับคุณ

https://github.com/dczhu/ltcd

ป้อนคำอธิบายรูปภาพที่นี่

มันมีคุณสมบัติดังต่อไปนี้เพื่อทำให้ชีวิตง่ายขึ้น:

  • รายการ Global dir ซึ่งแสดง dirs ที่เยี่ยมชมล่าสุดจากแท็บเทอร์มินัล / หน้าต่างทั้งหมด
  • รายชื่อ dir ท้องถิ่นซึ่งเป็นท้องถิ่นเซสชั่นเปลือกปัจจุบัน
  • รายการทั้งสองรองรับการนำทางอย่างรวดเร็วโดยใช้ j / k (เลื่อนขึ้น / ลง), ตัวเลขและค้นหาคำ
  • การกระโดดข้ามโลกฟรี (เช่น "cd dir" หรือ "cd ar" เพื่อไปที่ / path / to / foo / bar / directory /)

หืมดูมีแนวโน้ม ฉันจะตรวจสอบมันออก
ddnomad

1

สำหรับทุบตีโดยทั่วไป: แทนที่จะใช้ cd ใช้pushdเพื่อเปลี่ยนไดเรกทอรีดังนั้นพวกเขาจะถูกบันทึกไว้ (หมายถึงซ้อนกัน)

pushd /home; pushd /var; pushd log

หากต้องการดูการใช้สแต็กdirsและการนำทางที่ง่ายขึ้น (เพื่อรับหมายเลขของการใช้ "รายการสแต็ก":

dirs -v

เอาท์พุท:

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

ตอนนี้ใช้ตัวเลขเหล่านี้ด้วยcdและ~ชอบ:

cd ~1

แต่ตอนนี้ตัวเลขเหล่านี้ถูกจัดเรียงใหม่ในขณะนี้และตำแหน่ง "0" จะเปลี่ยนดังนั้นpushdไดเรกทอรีไปยังตำแหน่งบนสุดสองครั้ง (หรือใช้จำลองที่ตำแหน่ง 0) เช่น:

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

ตอนนี้ 1..3 จะยังคงอยู่ในตำแหน่งที่ ฉันอ่านนี่ที่ไหนสักแห่ง แต่ไม่รู้อีกต่อไปดังนั้นขอโทษที่ไม่ให้เครดิต

(เพื่อปล่อยไดเรกทอรีปัจจุบันจากสแต็ค / ลบออกจากการใช้ประวัติpopd)


1

ดูฟังก์ชั่น cdh ใน "Shell Programming, 4e" ที่หน้า 312 ซึ่งจะเก็บประวัติไว้ในอาร์เรย์

นี่คือรุ่นขั้นสูงเพิ่มเติม: https://drive.google.com/open?id=0B4f-lR6inxQWQ1pPZVpUQ3FSZ2M

มันเก็บประวัติในไฟล์ CDHISTFILE และช่วยให้การเปลี่ยนไปยังไดเรกทอรีล่าสุดที่มีสตริงเช่น

cd -src

มันติดตั้งตัวเองเหนือคำสั่ง cd ที่มีอยู่โดยการทำ alias cd=_cd


1

แค่ต้องการเพิ่มเครื่องหมาย fzfเป็นทางออกที่เป็นไปได้

เมื่อติดตั้งแล้วมันจะให้คำสั่งทำเครื่องหมายและข้ามไปเพื่อเพิ่มและค้นหาไดเรกทอรีบุ๊กมาร์ก (ใช่มันไม่ตรงกับประวัติทั้งหมดเพียงอย่างเดียวที่คุณทำบุ๊กมาร์กด้วยตนเอง)

ปัญหาที่ฉันมีกับ pushd / popd มันคือพฤติกรรมที่เฉพาะเจาะจงของเซสชั่นเช่นฉันต้องการที่จะมีกองเดียวกันในเซสชั่นทุบตีที่แตกต่างกันหรือเพื่อที่เป็นไปได้สำหรับเครื่องหมาย fzf


0

ฉันลองตอบ @mikeserv ให้ แต่ก็ไม่ได้ผลสำหรับฉัน ฉันไม่สามารถหาวิธีแก้ไขได้ดังนั้นฉันจึงเขียนเอง:

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

นอกจากนี้ยังสามารถใช้ได้เป็นGitHub สรุปสาระสำคัญ เมื่อต้องการใช้นี้เพียงแค่วางฟังก์ชั่นลงในของคุณ.bashrcที่คล้ายกันหรือและคุณจะสามารถที่จะทำสิ่งที่ต้องการcd -5ที่จะกลับไป 5 THไดเรกทอรีสุดท้ายที่คุณได้รับใน. cd -hจะให้ภาพรวมของประวัติของคุณ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.