ทางลัดไดเรกทอรีทุบตี


28

เมื่อฉันพิมพ์cd ~fooฉันต้องการทุบตีที่จะพาฉันไปยังไดเรกทอรีบางเป็นทางลัดสำหรับการพิมพ์เส้นทางไดเรกทอรีเต็มรูปแบบของfoo fooและฉันต้องการที่จะสามารถcp ~foo/bar.txt ~/bar.txtคัดลอกไฟล์จาก/foo/ไดเรกทอรีไปยังโฮมไดเร็กตอรี่ ... ดังนั้นโดยทั่วไปฉันต้องการบางสิ่งที่ทำงานได้ดีอย่างที่ต้องการ~/แต่ที่ฉันระบุสิ่งที่ไดเรกทอรีควรจะเป็น [ฉันแน่ใจว่าฉันควร jfgi แต่ฉันไม่รู้จะ fg]


zshมีการสนับสนุนในตัวสำหรับสิ่งนี้ มันเรียกว่า " ไดเรกทอรีที่มีชื่อ "
Sildoreth

ฉันกำลังมองหาเครื่องมือคั่นหน้าเชลล์นานเกินไปและในที่สุดฉันก็ลงเอยด้วยตัวเอง (ตามฟัซซี่ - ค้นหา) ที่ฉันชอบมากกว่าที่เคยเห็นมาก่อน ตรวจสอบคำตอบนี้: unix.stackexchange.com/a/209892/46011
Dmitry Frank

คำตอบ:


39

วิธีที่ฉันใช้ในการทำเช่นนี้คือการสร้างไดเรกทอรีที่มี symlinks ไปยังไดเรกทอรีที่คุณต้องการใช้ทางลัดและเพิ่มไดเรกทอรีนั้นลงใน CDPATH ของคุณ CDPATH จะควบคุมตำแหน่งที่cdจะค้นหาเมื่อคุณสลับไดเรกทอรีดังนั้นหากไดเรกทอรีของ symlink นั้นอยู่ใน CDPATH ของคุณคุณสามารถcdไปยังไดเรกทอรี symlinked ใด ๆ ได้ทันที:

mkdir ~/symlinks
ln -s /usr/bin ~/symlinks/b
export CDPATH=~/symlinks
cd b   # Switches to /usr/bin

ข้อเสียของหลักสูตรคือจะไม่ทำงานหากมีไดเรกทอรีในไดเรกทอรีปัจจุบันของคุณชื่อ "b" - ซึ่งมีความสำคัญเหนือ CDPATH


ปกติแล้วฉันไม่ชอบคำตอบที่พูดว่า "ก่อนอื่นคุณต้องเปลี่ยนหอย" แต่คุณสมบัติที่แน่นอนนี้มีอยู่ในZSHถ้าคุณเต็มใจที่จะใช้มันแทน ก็เรียกว่าไดเรกทอรีที่มีชื่อ คุณส่งออกตัวแปรfooและเมื่อคุณดูมันหายไปค่าของ~foo $fooนี้จะสะดวกโดยเฉพาะอย่างยิ่งเพราะการทำงานในคำสั่งนอกเหนือจากcd:

echo hi > /tmp/test
export t=/tmp
cat ~t/test   # Outputs "hi"

2
คุณลักษณะ ZSH นี้แตกต่างกันอย่างไรในการทำ: echo hi> / tmp / test; export t = / tmp; cat $ t / test อย่างน้อยในเครื่องของฉันมันใช้งานได้ดี ข้อแตกต่างคือตัวละครที่คุณต้องพิมพ์
Steven D

การอ้างถึง op to zsh เป็นสิ่งที่ถูกต้อง ฉันไม่เคยพลาดฟีเจอร์นี้สักครั้งในรอบ 15 ปี ดูเหมือนว่าเป็นสิ่งที่บางคนหลงไหลในขณะที่คนอื่นไม่สนใจ นั่นเป็นเหตุผลที่มีมากกว่าหนึ่งเชลล์

2
@Steven มันค่อนข้างคล้ายกัน แต่ ZSH รู้ว่ามันเป็นไดเร็กตอรี่ที่มีชื่อในกรณีนี้ดังนั้นมันจึงสามารถรักษามันได้เป็นพิเศษในการขยายและพร้อมท์คำสั่งในตัวเชลล์
Michael Mrozek

[ฉันส่วนใหญ่จะทำเช่นนี้โดยใช้ emacs Mx เปลือก (ตั้งแต่ที่เมื่อฉันใช้ขั้ว) ผมคิดว่ากฎที่ออกโซลูชั่น ZSH] ...
เชมัส

1
เพิ่มลงใน. zshrc ของฉันและใช้งานได้
เชมัส

10

คุณสามารถเขียนฟังก์ชั่น wrapper สำหรับcdและเรียกมันว่า "cd" (ในที่สุดฟังก์ชั่นจะเรียกbuiltin cd- ใช้builtinคำหลัก) คุณสามารถใช้อักขระนำหน้าที่ Bash จะไม่ขยายในบรรทัดคำสั่งก่อนที่ฟังก์ชันของคุณจะเห็นและไม่น่าจะปรากฏเป็นอักขระเริ่มต้นในชื่อไดเรกทอรีของคุณซึ่งอาจเป็น ":" คุณต้องการทำให้มันแข็งแกร่งขึ้น แต่นี่เป็นโครงร่างที่เรียบง่าย:

# format: [semicolon] shortcut colon destination [semicolon] ...
export CDDATA='foo:/path/to/foo;bar:/path/to/bar;baz:/path/to/baz'

cd () {
    local dest=$1
    if [[ $dest == :* ]]
    then
        [[ $CDDATA =~ (^|;)${dest:1}:([^;]*)(;|$) ]]
        dest=${BASH_REMATCH[2]}
    fi
    if [[ -z $dest ]]
    then
        cd
    else
        builtin cd "$dest"
    fi
}

cd :bar    # pwd is now /path/to/bar

1
นี่เป็นความคิดที่ดีจริงๆ
Michael Mrozek

ขอบคุณสำหรับคำแนะนำนี้ - สร้างโซลูชันที่ง่ายที่สุดของฉัน: aaverin.github.io/unix/macox/2014/05/26/bash-named-folders
AAverin

7

ด้วยทุบตี:

~fooสงวนไว้สำหรับโฮมไดเร็กทอรีของผู้ใช้ foo ฉันจะไม่แนะนำให้สร้างผู้ใช้เพียงเพื่อความสะดวก

คุณสามารถทำให้ชีวิตของคุณง่ายขึ้น (หรือยากขึ้น) เมื่อเปลี่ยนไดเรกทอรีโดยการตั้งค่าCDPATHตัวแปรสภาพแวดล้อม (ค้นหาในbash(1))

นอกจากนั้นวิธีเดียวที่จะคิดคือการตั้งค่าตัวแปรสภาพแวดล้อมสำหรับไดเรกทอรีเหล่านั้นที่คุณต้องการย่อ

$ FOODIR=/var/lib/misc
$ cp ~/bar.txt $FOODIR

2

ตัวแปร Bash สามารถใช้สร้างระบบคั่นหน้าได้ ตัวแปรจะทำงานกับคำสั่งใดก็ได้และแท็บ bash จะทำให้ชื่อตัวแปรสมบูรณ์ ในเวอร์ชันที่ใหม่กว่าของ bash หาก a / ถูกผนวกเข้ากับชื่อตัวแปรพา ธ ที่ตัวแปรนั้นมีสามารถแท็บเสร็จสมบูรณ์ได้เช่นกัน

mydir=/home/chris/dir
ls $my         # Tab completion works on variable name.
ls $mydir/     # Tab completion is equivalent to that with ls /home/chris/dir/
               # (doesn't work in older versions of bash).

สำหรับการคงอยู่การประกาศตัวแปรสามารถเก็บไว้ในไฟล์ที่มาจาก. bashrc เนื่องจากไฟล์นี้เป็นสคริปต์ทุบตีจึงสามารถมีการประกาศที่อ้างอิงตัวแปรอื่น ๆ เช่นaur="${HOME}/AUR"หรือที่ทำงานเฉพาะกับโฮสต์บางโฮสต์if [[ $HOSTNAME == foo ]]; then bar=baz; fiเท่านั้นซึ่งมีประโยชน์หากคุณใช้ไฟล์กำหนดค่าซ้ำในหลาย ๆ โฮสต์และผู้ใช้

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

bookmark_file=~/.bookmarks
source "$bookmark_file"

bm() {
usage='Usage:
bm add <name> <path>           Create a bookmark for path.
bm add <name>                  Create a bookmark for the current directory.
bm update                      Source the bookmark file.
bm remove <name>               Remove a bookmark'              

case $1 in
    add)
        local path
        if [[ $# -eq 2 ]]; then
            path=.
        elif [[ $# -eq 3 ]]; then
            if [[ -e $3 ]]; then
                path="$3"
            else
                echo "bm: ${3}: No such file or directory."
                return 1
            fi               
        else
            echo "$usage"
            return 1
        fi

        if declare | grep "^${2}=" > /dev/null; then
            echo "bm: The name $2 is in use."
            return 1
        fi
        path=$(readlink -f "$path")
        echo ${2}=\""$path"\" >> "$bookmark_file"
        eval ${2}=\""$path"\"
        return 0
        ;;
    update)
        if [[ $# -eq 1 ]]; then
            source "$bookmark_file"
            return 0
        fi
        ;;
    remove)
        if [[ $# -eq 2 ]]; then
            unset $2
            local contents=$(grep -v "^${2}=" "$bookmark_file")
            echo "$contents" > "${bookmark_file}.tmp"
            rm -f "$bookmark_file"
            mv "${bookmark_file}.tmp" "$bookmark_file"
            return 0
        fi
        ;;
esac

echo "$usage"
return 1
}

0

วิธีหนึ่งคือการสร้างนามแฝงสำหรับ cd ซึ่งแทนที่~cเส้นทางที่ต้องการ หรือเพียงแค่ใช้ zsh;)


2
ใช่ฉันคิดเกี่ยวกับการทำเช่นนามแฝง ~ c = "cd / daten / cvs / plugin_root" แต่ที่ช่วยด้วย cd เท่านั้นในขณะที่ไดเรกทอรีชื่อสามารถใช้กับทุกคำสั่ง
fschmitt

0

สำหรับการเปลี่ยนไดเรกทอรีคุณสามารถใช้ wcd: Wereever Change Directory

ด้วยสิ่งนั้นมันจะเป็นเช่นwcd plugin_rootนั้น


ฉันต้องการบางสิ่งบางอย่างที่ทำงานร่วมกับคำสั่งอื่น ๆ มากกว่าcdเช่นกัน ...
เชมัส

0

ฉันมีฟังก์ชั่นด้านล่างซึ่งจะสร้างนามแฝงได้ทันที

s () {
    if [[ "x$1" != "x" ]]
    then
        alias $1="cd $PWD;pwd"
        echo "alias $1=\"cd $PWD;pwd\""
    else
        echo "Usage: s[s] <directory bookmark name>"
        return 1
    fi
}

s dirNameเมื่อฉันต้องการบุ๊คมาร์คไดเรกทอรีฉันเพียงแค่พิมพ์ alias dirName="cd /my/current/directory/;pwd"นี้จะสร้างชื่อแทนเช่น dirNameดังนั้นฉันสามารถกลับมาไดเรกทอรีนี้โดยเพียงแค่พิมพ์ ฉันมีเวอร์ชันที่บันทึกลงใน bash_aliases เช่นกัน ใช้ได้กับทุกเชลล์

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