คุณจะ cd ไปยังไดเรกทอรีของหน้าต่างหน้าจออื่นได้อย่างไร


0

gnome-terminal มีคุณสมบัติที่ยอดเยี่ยมที่การเปิดแท็บหรือหน้าต่างใหม่จะเริ่มเชลล์ใหม่ด้วย cwd = the cwd ของหน้าต่างที่เน้นก่อนหน้านี้

ฉันมักจะเรียกใช้หน้าจอ GNU ในแท็บ gnome-terminal ของฉัน ส่วนหนึ่งสำหรับ scrollback ส่วนหนึ่งสำหรับการแสดงผลขนาดกะทัดรัดและ enumarated จาก 5 ถึง 10 windows ส่วนหนึ่งสำหรับการกดแป้นอย่างรวดเร็วเพื่อสลับไปยังแท็บเฉพาะหรือแท็บก่อนหน้า

แต่ฉันเริ่มอยากจะทำ cd ในหน้าต่างหนึ่งไปยัง CWD ของหน้าต่างอื่น คำถามคืออย่างไร

(BTW เป็น stackexchange Q & amp; self-A เป็นวิธีที่เหมาะสมในการแบ่งปันนามแฝงที่ประณีตฟังก์ชั่นเชลล์หรือแฮ็คเช่นนี้ที่ฉันคิดขึ้นมาฉันไม่มีบล็อกและฉันไม่คิดว่าตัวสั่นด้วยความตื่นเต้นหรือ facebook จะเป็นตัวเลือกที่ดี)

คำตอบ:


0

วิธีนี้เป็นแบบพกพาไปยังระบบ Unix ใด ๆ แต่ขึ้นอยู่กับการทำงานของ GNU ทุบตี cd -P ที่จะทำให้มันไม่น่าเกลียด

วางสิ่งนี้ (หรือรุ่นอื่นด้านล่างซึ่งเก็บรักษาไดเรกทอรีตรรกะ) ไว้ในของคุณ ~/.bashrc (หรือ .zshrc หรืออะไรก็ตาม) ดังนั้นมันจะทำงานสำหรับเชลล์แบบโต้ตอบทุกอัน (ภายในและภายนอกหน้าจอ):

CDS_PREFIX="/var/run/screen/S-$USER"  # screen uses this already
#CDS_PREFIX="/dev/shm/screen-$USER" # if /var/run isn't on tmpfs
# $STY = a string unique to the screen session
if [[ $STY ]]; then
        CDS_DIR="$CDS_PREFIX/dirs.$STY"
        unset CDS_PREFIX

        [[ -d $CDS_DIR ]] || mkdir -m 700 -p "$CDS_DIR"

        # old cmd-every-prompt design: avoids breakage if you run interactive bash from bash, then exit
        # Also, use this on systems without a /proc/<pid>/cwd
        #PROMPT_COMMAND='[[ $WINDOW ]] && ln -sf "$PWD" "$CDS_DIR/$WINDOW"'

        ln -sTf "/proc/$$/cwd" "$CDS_DIR/$WINDOW"       # -T saves a stat call
        cds() { cd -P "$CDS_DIR/$@"; }
else
        # CDS_DIR=( "$CDS_PREFIX"/dirs.* )  # cds will use the first array element
        cds() { cd -P "$CDS_PREFIX/"dirs.*/"$@"; }  # even support shells started before screen.  cd with multiple args takes the first one without complaint.
fi

ดังนั้นคุณสามารถเปิดหน้าต่างหน้าจอใหม่และ cds 5 จะนำคุณไปยัง cwd ของเชลล์ในหน้าต่าง 5

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

ค่าใช้จ่ายทั้งหมด:

  • ในทุกการเริ่มต้นเชลล์แบบโต้ตอบ:
    • 8 บรรทัดที่ไม่ใช่ความคิดเห็นของรหัสในการแยกวิเคราะห์
    • สถิติ
    • ln -sTf ไปยังไดเร็กทอรีบน tmpfs
  • โอเวอร์เฮดหน่วยความจำอย่างต่อเนื่องหลังจากเชลล์เริ่มทำงาน:
    • 1 shell var และ 1 small function
    • ไม่มีสภาพแวดล้อม vars
  • การจัดเก็บ:
    • ไดเรกทอรีหนึ่ง symlink ต่อหน้าต่างหน้าจอ (ไม่ถูกลบหลังจากปิดหน้าต่าง)
  • ต่อคำสั่ง:
    • ไม่มี

ไม่มี cd -P, \w ในของคุณ $PS1 จะขยายเป็น /proc/3069/cwdไม่ใช่เส้นทางที่เป็นที่ยอมรับ (ตามด้วย symlink) ที่คุณได้รับ -P.

เวอร์ชันที่ใช้ PROMPT_COMMAND สามารถแก้ไขได้ cds() เพื่อ cd เพื่อนำคุณไปยังไดเรกทอรีโลจิคัล (เก็บ CWD เป็นข้อความในไฟล์แทนที่จะเป็น symlink pwd > "$CDS_DIR/$WINDOW" เป็นเพียง shell builtin ดังนั้นค่าใช้จ่ายน้อยกว่า fork / execing ไบนารี นอกจากนี้ยังบันทึกปัญหาในการหลีกเลี่ยง GNU ที่หายไป readlink บนบางระบบที่ไม่ใช่ Linux) สิ่งนี้จะมีประโยชน์หากคุณมักจะทำงานใน symlink ไปยังไดเรกทอรีที่ pwd -P (และ /bin/pwd ) ไม่เหมือนกับ pwd.

คุณสามารถแทนที่ cd, pushdและ popd builtins พร้อมฟังก์ชั่นที่อัปเดต symlink แทนที่จะทำทุกคำสั่ง ด้วยการตั้งค่านั้นการใช้สิ่งโต้ตอบเช่น (cd foo; command there) จะหลอกการตั้งค่าของคุณเพราะ cd ที่ทำงานใน subshell จะอัพเดท symlink แต่ไม่มีการแก้ไข pwd ของกระบวนการเชลล์หลัก

ตกลงนี่เป็น "รุ่นอื่น" ที่เกี่ยว cd, pushdและ popdและจะนำคุณไปยังไดเรกทอรีโลจิคัลเดียวกับเชลล์ในหน้าต่างหน้าจอใด ๆ :

# Use this version on systems without `/proc/<pid>/cwd`, or for logical directories (non-dereferencing of symlinks).

CDS_PREFIX="/var/run/screen/S-$USER"
#CDS_PREFIX="/dev/shm/screen-$USER"
if [[ $STY ]]; then
    CDS_DIR="$CDS_PREFIX/dirs.$STY"
    unset CDS_PREFIX
    [[ -d $CDS_DIR ]] || mkdir -m 700 -p "$CDS_DIR"

    function cd    () { command cd    "$@"; pwd > "$CDS_DIR/$WINDOW"; }
    function pushd () { command pushd "$@"; pwd > "$CDS_DIR/$WINDOW"; }
    function popd  () { command popd  "$@"; pwd > "$CDS_DIR/$WINDOW"; }
    #PROMPT_COMMAND='[[ $WINDOW ]] && pwd > "$CDS_DIR/$WINDOW"'
    if [[ -e "$CDS_DIR/$WINDOW" && ! -f "$CDS_DIR/$WINDOW" ]]; then
        rm -f "$CDS_DIR/$WINDOW"  # could exist if switching from symlink-to-dir style
    fi
    cd .

#   cds() { local d="$(<"$CDS_DIR/$1")"; shift; cd "$d" "$@"; }
    cds() { cd "$(<"$CDS_DIR/$1")"; }
else
    # CDS_DIR=( "$CDS_PREFIX"/dirs.* )  # cds will use the first array element
    cds() { cd "$(<"$CDS_PREFIX/"dirs.*/"$1")"; }  # even support shells started before screen.
fi

ค่าใช้จ่าย: open(2) และ write(2) เป็น tmpfs สำหรับทุกคน cd, pushdและ popd คุณพิมพ์หรือวางมิฉะนั้นจะเหมือนกัน ยังคงไม่เจ็บในระบบใด ๆ ที่ทรงพลังพอที่จะรัน bash และ screen ในที่แรก. :)

ให้เครดิตกับ https://superuser.com/a/54161/20798 สำหรับแนวคิดของ hooking cd ฉันชอบที่ดีกว่ามาก PROMPT_COMMAND. พบว่าในขณะที่มองเพื่อดูว่ามีคนอื่นคิดค้นนี้และไม่ว่าฉันควรโพสต์ที่นี่หรือบน https://unix.stackexchange.com/ .

ฉันใช้ bash-isms (เช่น [[ ]] ) เพราะฉันคิดว่า zsh ก็สนับสนุนพวกเขาด้วยและหวังว่าจะไม่มีใครใช้ POSIX sh เป็นเชลล์เชิงโต้ตอบของพวกเขา

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