Apa cara baris perintah cepat untuk beralih di antara banyak direktori untuk administrasi sistem?

46

Apa cara baris perintah cepat untuk beralih di antara banyak direktori untuk administrasi sistem? Maksud saya, saya dapat menggunakan pushd .dan popdberalih, tetapi bagaimana jika saya ingin menyimpan kelipatan dan memutarnya, daripada secara permanen mengeluarkannya dari bagian bawah tumpukan?

Volomike
sumber
$CDPATHmungkin?
roaima
6
oh my - saya baru belajar cd -setelah googling dihasut dari pertanyaan ini.
Nacht - Pasang kembali Monica
@ Kapal: Bagaimana Anda menavigasi struktur file sebelumnya ??
loneboat
1
Di cdmana-mana dengan tangan. Sangat menyakitkan. Namun, pelengkapan otomatis yang digunakan dengan tombol tab.
Volomike
1
Mungkin Anda ingin mencoba . Sangat berguna ketika Anda banyak melompat dalam beberapa dir yang sama.
Rolf

Jawaban:

28

Gunakan pushddan kemudian nama-nama khusus untuk direktori di direktori stack Anda: ~1, ~2, dll

Contoh:

tmp $ dirs -v
 0  /tmp
 1  /tmp/scripts
 2  /tmp/photos
 3  /tmp/music
 4  /tmp/pictures
tmp $ cd ~3
music $ dirs -v
 0  /tmp/music
 1  /tmp/scripts
 2  /tmp/photos
 3  /tmp/music
 4  /tmp/pictures
music $ cd ~2
photos $ cd ~4
pictures $ cd ~3
music $ cd ~1
scripts $ 

Cara paling efektif untuk digunakan pushddengan cara ini adalah memuat daftar direktori Anda, kemudian menambahkan satu direktori lagi menjadi direktori Anda saat ini, dan kemudian Anda dapat melompat di antara angka-angka statis tanpa mempengaruhi posisi direktori di tumpukan Anda.


Perlu juga dicatat bahwa cd -akan membawa Anda ke direktori terakhir tempat Anda berada. Begitu juga cd ~-.

Keuntungan dari ~-atas hanya -adalah bahwa -khusus untuk cd, sedangkan ~-diperluas oleh shell Anda dengan cara yang sama ~1, ~2, dll. Ini sangat berguna saat menyalin file di antara jalur direktori yang sangat panjang; misalnya:

cd /very/long/path/to/some/directory/
cd /another/long/path/to/where/the/source/file/is/
cp myfile ~-

Di atas setara dengan:

cp /another/long/path/to/where/the/source/file/is/myfile /very/long/path/to/some/directory/
Wildcard
sumber
1
Bisa juga menggunakancd -
Volomike
cd -bertindak seperti Forth DROP DUP, misalnya jika seseorang mulai dengan di direktori a , dengan stack abcd , a cd -mengubah stack menjadi bbcd . Mungkin itu bashbug, karena yang kedua cd -mengubah stack kembali ke abcd . Dari sini kita dapat menyimpulkan bahwa cd -menggunakan beberapa struktur data terpisah untuk menyimpan direktori sebelumnya, selain mengubah tumpukan.
AGC
3
@ Agc, cd -kegunaan $OLDPWDdan tidak ada yang lain.
Wildcard
Jadi mungkin fitur bashcd - sebelumnya , kemudian mereka menambahkan tumpukan, tetapi takut melanggar kode lama lebih dari yang mereka inginkan desain yang lebih sederhana. Koreksi ke sebelumnya, bertindak seperti Forth Berbeda , mencetak nama direktori swapped-in. cd -OLDPWD @ SWAP OLDPWD ! DUP .cd foocd -
agc
Atau selalu ada pembungkus pushd interaktif (jawaban lain untuk pertanyaan itu termasuk autojump dll.).
berguna
42

bashbuiltin pushddengan opsi +dan -dapat memutar tumpukan direktori. Sintaksnya bisa sedikit membingungkan, mungkin karena tumpukan itu adalah array berbasis nol . Fungsi pembungkus sederhana ini berputar melalui tumpukan direktori:

# cd to next     directory in stack (left  rotate)
ncd(){ pushd +1 > /dev/null ; }
# cd to previous directory in stack (right rotate)
pcd(){ pushd -0 > /dev/null ; }

Tes: mengatur tumpukan empat direktori.

dirs -c   # clear directory stack
cd /home ; pushd /etc ; pushd /bin ; pushd /tmp

Sekarang / tmp adalah direktori saat ini, dan tumpukan terlihat seperti:

/tmp /bin /etc /home

Ubah ke direktori berikutnya dalam tumpukan, (dan perlihatkan), empat kali:

ncd ; pwd ; ncd ; pwd ; ncd ; pwd ; ncd ; pwd

Keluaran:

/bin
/etc
/home
/tmp

Ubah ke direktori sebelumnya dalam tumpukan, (dan perlihatkan), empat kali:

pcd ; pwd ; pcd ; pwd ; pcd ; pwd ; pcd ; pwd

Keluaran:

/home
/etc
/bin
/tmp

Catatan tentang cd -: Jawaban Wildcard membantu menggambarkan bagaimana cd -tidak menggunakan array $ DIRSTACK , (menggunakan variabel $ OLDPW ), sehingga cd -tidak mempengaruhi $ DIRSTACK seperti seharusnya swap berbasis stack. Untuk memperbaikinya, inilah fungsi swap sederhana berbasis $ DIRSTACK :

scd() { { pushd ${DIRSTACK[1]} ; popd -n +2 ; } > /dev/null ; }

Uji:

dirs -c; cd /tmp; \
pushd /bin; \
pushd /etc; \
pushd /lib; \
pushd /home; \
scd; dirs; scd; dirs

Keluaran:

/bin /tmp
/etc /bin /tmp
/lib /etc /bin /tmp
/home /lib /etc /bin /tmp
/lib /home /etc /bin /tmp
/home /lib /etc /bin /tmp
agc
sumber
Frustrasi saya adalah saya ingin meletakkan barang-barang di tumpukan dan menyimpannya di sana sampai saya memilih untuk menghapus tumpukan. Dengan begitu, saya bisa mendorong, mendorong, mendorong, lalu memutari masing-masing dari tiga dir yang diperlukan. Katakan misalnya saya perlu membalik di antara tiga direktori seolah-olah mereka seperti tab browser, dan bolak-balik, sampai saya menutup tab. Apakah ini mengatasi ini dengan cara baris perintah?
Volomike
5
Ya, saya percaya ya, coba saja. Untuk menghapus item teratas, lakukan popd, untuk menghapusnya tanpa mengubah dir, lakukan popd -n. Untuk menghapus tumpukan lakukan dirs -c. Sayang sekali para desainer bash mengubur fungsi-fungsi bermanfaat seperti itu dalam sintaksis non-intuitif. Lihat di man bashbawah pushd,, dirsdll.
agc
Bekerja! Dan jelas seperti lumpur di dokumen. Saya suka kesederhanaannya, sekarang saya tahu tekniknya.
Volomike
13

Saya sarankan Anda menginstal fasd . Ini memberi Anda kemampuan untuk dengan cepat melompat ke direktori mana pun Anda sudah berada dengan mengetikkan hanya sebagian kecil dari namanya.

Contoh: jika Anda mengunjungi /home/someName/scripts/, Anda bisa melompat ke sana hanya dengan mengetik z scrmisalnya. Itu jauh lebih nyaman jika mengingat urutan di tumpukan riwayat atau yang serupa.

kaqqao
sumber
10

Saat Anda berada di cdsuatu tempat, Bash menyimpan variabel lingkungan direktori kerja lama $OLDPWD,.

Anda dapat beralih kembali ke direktori dengan cd -, yang setara dengan cd "$OLDPWD".

Anda dapat bangkit bolak-balik antara direktori seperti:

blue$ cd ~/green
green$ cd -
blue$ cd -
green$
RJHunter
sumber
6

Saya menulis sebuah skrip bernama xyzzyuntuk melakukan ini:

#!/bin/bash

i="$1"
i=$((${i//[^0-9]/}))
i="$(($i-1+0))"

b="$2"
b=$((${b//[^0-9]/}))
b="$(($b-1+0))"

if [ -z "$XYZZY_INDEX" ]; then
    XYZZY_INDEX="$((-1))"
fi

if [ ! -f "/tmp/xyzzy.list" ]; then
    touch /tmp/xyzzy.list
    chmod a+rw /tmp/xyzzy.list
fi
readarray -t MYLIST < /tmp/xyzzy.list

showHelp(){
read -r -d '' MYHELP <<'EOB'
xyzzy 1.0

A command for manipulating escape routes from grues. Otherwise known as a useful system admin
tool for storing current directories and cycling through them rapidly. You'll wonder why this
wasn't created many moons ago.

Usage: xyzzy [options]

help/-h/--help      Show the help.

this/-t/--this      Store the current directory in /tmp/xyzzy.list

begone/-b/--begone  Clear the /tmp/xyzzy.list file. However, succeed with a number and
            it clears just that item from the stored list.

show/-s/--show      Show the list of stored directories from /tmp/xyzzy.list

. #         Use a number to 'cd' to that directory item in the stored list. This syntax is odd:

            . xyzzy 2

            ...would change to the second directory in the list

. [no options]      Use the command alone and it cd cycles through the next item in the stored 
            list, repeating to the top when it gets to the bottom. The dot and space before xyzzy
            is required in order for the command to run in the current shell and not a subshell:

            . xyzzy

Note that you can avoid the odd dot syntax by adding this to your ~/.bashrc file:

  alias xyzzy=". xyzzy"

and then you can do "xyzzy" to cycle through directories, or "xyzzy {number}" to go to a
specific one.

May you never encounter another grue.

Copyright (c) 2016, Mike McKee <https://github.com/volomike>
EOB
    echo -e "$MYHELP\n"
}

storeThis(){
    echo -e "With a stroke of your wand, you magically created the new escape route: $PWD"
    echo "$PWD" >> /tmp/xyzzy.list
    chmod a+rw /tmp/xyzzy.list
}

begoneList(){
    if [[ "$b" == "-1" ]]; then
        echo "POOF! Your escape routes are gone. We bless your soul from the ever-present grues!"
        >/tmp/xyzzy.list
        chmod a+rw /tmp/xyzzy.list
    else
        echo -n "Waving your wand in the dark, you successfully manage to remove one of your escape routes: "
        echo "${MYLIST[${b}]}"
        >/tmp/xyzzy.list
        chmod a+rw /tmp/xyzzy.list
        for x in "${MYLIST[@]}"; do
            if [[ ! "$x" == "${MYLIST[${b}]}" ]]; then
                echo "$x" >> /tmp/xyzzy.list
            fi
        done
    fi
}

showList(){
    echo -e "These are your escape routes:\n"
    cat /tmp/xyzzy.list
}

cycleNext(){
    MAXLINES=${#MYLIST[@]}
    XYZZY_INDEX=$((XYZZY_INDEX+1))
    if [[ $XYZZY_INDEX > $(($MAXLINES - 1)) ]]; then
        XYZZY_INDEX=0
    fi
    MYLINE="${MYLIST[${XYZZY_INDEX}]}"
    cd "$MYLINE";
}

switchDir(){
    MYLINE="${MYLIST[${i}]}"
    cd "$MYLINE";
}

if [[ "$@" == "" ]];
then
    cycleNext
fi;

while [[ "$@" > 0 ]]; do case $1 in
    help) showHelp;;
    --help) showHelp;;
    -h) showHelp;;
    show) showList;;
    -s) showList;;
    --show) showList;;
    list) showList;;
    this) storeThis;;
    --this) storeThis;;
    -t) storeThis;;
    begone) begoneList;;
    --begone) begoneList;;
    *) switchDir;;
    esac; shift
done

export XYZZY_INDEX

Cara saya menggunakan ini adalah menyalin ke dalam /usr/binfolder dan kemudian chmod a+xdi atasnya. Lalu, saya mengedit ~/.bashrcfile akun root dan akun pengguna saya untuk memasukkan baris-baris ini di bagian bawah:

alias xyzzy='. xyzzy'
alias xy='. xyzzy'

'Xy' adalah bentuk singkat dari perintah untuk mengetik lebih cepat.

Lalu, saya dapat menyimpan direktori saat ini dalam daftar dengan ...

xyzzy this

... dan ulangi seperlunya. Setelah saya mengisi daftar ini dengan direktori yang saya butuhkan, mereka tetap di sana sampai saya me-reboot komputer karena saat itulah / tmp dihapus lagi. Saya kemudian dapat mengetik ...

xyzzy show

... untuk mendaftar direktori yang saat ini disimpan. Untuk beralih ke direktori, saya punya dua pilihan. Salah satu opsi adalah menentukan jalur dengan indeks (dan ini adalah indeks berbasis 1) seperti:

xyzzy 2

... yang akan beralih ke direktori itu item kedua dalam daftar. Atau, saya dapat mengabaikan nomor indeks dan lakukan:

xyzzy

... untuk memilikinya loop melalui setiap direktori yang saya butuhkan. Untuk perintah lain yang bisa Anda lakukan, ketik:

xyzzy help

Tentu saja, bekerja lebih menyenangkan dengan pernyataan gema konyol yang saya tambahkan.

Perhatikan bahwa xyzzy adalah referensi ke petualangan teks Gua Collosal , di mana mengetik xyzzy akan memungkinkan Anda beralih di antara dua kamar dalam permainan untuk menghindari grues.

Volomike
sumber
2
+1 Saya mulai bermain dengan ini. Ini bagus, tetapi tampaknya gagal jika belum ada direktori yang ditambahkan dan Anda hanya memasukkan xyzzy. Perlu satu tes lagi untuk MAXLINES -eq 0 di cyclenext ().
Joe
5

Saya menggunakan skrip kecil bernama z [tautan] , yang mungkin juga menarik, meskipun tidak melakukan persis apa yang Anda minta.

NAME
       z - jump around

SYNOPSIS
       z [-chlrtx] [regex1 regex2 ... regexn]

AVAILABILITY
       bash, zsh

DESCRIPTION
       Tracks your most used directories, based on 'frecency'.

       After  a  short  learning  phase, z will take you to the most 'frecent'
       directory that matches ALL of the regexes given on the command line, in
       order.

       For example, z foo bar would match /foo/bar but not /bar/foo.
Graipher
sumber
Mungkin saya melewatkan sesuatu, tetapi di mana saya dapat menemukan skrip z itu sendiri?
Joe
Maaf, tautannya ada di z. Akan diedit untuk membuatnya lebih mudah dilihat.
Graipher
5

Ada juga cd_funcdari Petar Marinov, pada dasarnya cddengan riwayat hingga 10 entri: http://linuxgazette.net/109/misc/marinov/acd_func.html

# do ". acd_func.sh"
# acd_func 1.0.5, 10-nov-2004
# petar marinov, http:/geocities.com/h2428, this is public domain

cd_func ()
{
  local x2 the_new_dir adir index
  local -i cnt

  if [[ $1 ==  "--" ]]; then
    dirs -v
    return 0
  fi

  the_new_dir=$1
  [[ -z $1 ]] && the_new_dir=$HOME

  if [[ ${the_new_dir:0:1} == '-' ]]; then
    #
    # Extract dir N from dirs
    index=${the_new_dir:1}
    [[ -z $index ]] && index=1
    adir=$(dirs +$index)
    [[ -z $adir ]] && return 1
    the_new_dir=$adir
  fi

  #
  # '~' has to be substituted by ${HOME}
  [[ ${the_new_dir:0:1} == '~' ]] && the_new_dir="${HOME}${the_new_dir:1}"

  #
  # Now change to the new dir and add to the top of the stack
  pushd "${the_new_dir}" > /dev/null
  [[ $? -ne 0 ]] && return 1
  the_new_dir=$(pwd)

  #
  # Trim down everything beyond 11th entry
  popd -n +11 2>/dev/null 1>/dev/null

  #
  # Remove any other occurence of this dir, skipping the top of the stack
  for ((cnt=1; cnt <= 10; cnt++)); do
    x2=$(dirs +${cnt} 2>/dev/null)
    [[ $? -ne 0 ]] && return 0
    [[ ${x2:0:1} == '~' ]] && x2="${HOME}${x2:1}"
    if [[ "${x2}" == "${the_new_dir}" ]]; then
      popd -n +$cnt 2>/dev/null 1>/dev/null
      cnt=cnt-1
    fi
  done

  return 0
}

alias cd=cd_func

if [[ $BASH_VERSION > "2.05a" ]]; then
  # ctrl+w shows the menu
  bind -x "\"\C-w\":cd_func -- ;"
fi

Hanya gunakan cd --untuk menunjukkan daftar masa lalu hingga 10 direktori yang Anda cdedit dan cd -N(di mana Nindeks entri) untuk pergi ke sana.

phk
sumber
4

Saya kebanyakan menggunakan ZSH dengan profil oh-my-zsh . Anda dapat mengetik ke terminal yang cocok dengan berikut:

# cd /ho

Kemudian Anda cukup menggunakan panah (atas dan bawah) untuk menelusuri semua riwayat shell yang hanya menampilkan entri yang dimulai dengan karakter di atas. Jadi, misalnya, jika Anda pergi ke /home/morfik/Desktop/dan /home/morfik/something/, Anda dapat beralih di antara direktori dengan sangat cepat. Tidak masalah berapa banyak entri dalam riwayat shell yang Anda miliki, tetapi ketika Anda memiliki banyak entri, cukup gunakan ekspresi yang lebih baik, yaitu cd /home/morfdan di sini tekan panah atas / bawah pada keyboard Anda.

Ada juga cara lain untuk mencapai solusi. Dalam hal ini Anda harus menggunakan tmux dan FZF . Kemudian Anda hanya membuat hotkey, misalnya ctrl-r, dan ketika Anda menekannya, jendela Anda saat ini akan dibagi dan Anda akan melihat ini:

masukkan deskripsi gambar di sini

Sekarang Anda dapat menggunakan ekspresi untuk mencari daftar. Saya baru saja mengetik ^cd /media, yang hanya mengembalikan entri yang dimulai dengan frasa. Tentu saja, Anda cukup mengetik 'cd 'homeuntuk mencocokkan perintah dan juga seluruh nama direktori (bukan path, hanya nama):

masukkan deskripsi gambar di sini

Mikhail Morfikov
sumber
4

Anda dapat mencapai ini dengan banyak alias di ~/.bashrc(atau setara) Anda

Tujuan utamanya adalah pengetikan mendekati minimum (mis. d5Melompat ke nomor direktori 5 di kumpulan) untuk beralih di antara direktori di kumpulan. Kami juga ingin membuatnya mudah untuk menambah / menghapus direktori ke / dari kumpulan:

alias pd=pushd
alias po=popd
alias d='dirs -v'
alias d0=d
alias d1='pd +1'
alias d2='pd +2'
alias d3='pd +3'
alias d4='pd +4'
alias d5='pd +5'
alias d6='pd +6'
alias d7='pd +7'
alias d8='pd +8'
alias d9='pd +9'
alias d10='pd +10'
# -- feel free to add more aliases if your typical dir pool is larger than 10

Sekarang setiap kali Anda mendorong direktori pada tumpukan itu akan ditambahkan ke kolam bernomor di posisi 0 (dir saat ini) dan Anda dapat melompat-lompat (beralih direktori) menggunakan sangat sedikit mengetik ( d<N>) dan Anda dapat melihat kolam saat ini bernomor Anda di mana saja waktu hanya dengan mengetik d.

Beberapa contoh penggunaan alias ini:

Tampilkan pool-dir bernomor, (dir saat ini adalah # 0)

$ d
 0  /tmp
 1  /
 2  /usr

Beralih di antara dir: gunakan d<N>

$ d2
$ pwd
/usr

Tambahkan direktori baru ke kumpulan

$ pd /var/log
$ d
 0  /var/log
 1  /usr
 2  /tmp
 3  /

Lompat lagi:

$ d3
$ pwd
/

$ d3
$ pwd
/tmp

$ d
 0  /tmp
 1  /
 2  /var/log
 3  /usr

Hapus / pop bagian atas (saat ini) dir dari kolam

$ po
$ d
 0  /
 1  /var/log
 2  /usr
diri sendiri
sumber
2

Jika Anda sudah menginstal iselect , Anda dapat melakukan sesuatu seperti ini:

$ alias dirselect='cd $(iselect -a $(dirs -l -p | sort -u))'
$ dirselect

Ini akan memberi Anda menu navigasi tombol panah interaktif berbasis ncurses layar penuh untuk memilih direktori cd.

Jika Anda belum pernah menggunakan pushdsesi shell saat ini, daftar direktori dalam menu dimulai hanya dengan satu entri, direktori Anda saat ini. Jika hanya ada satu entri, dirselectalias ini hanya akan cdke sana tanpa layar menu, sehingga secara efektif tidak melakukan apa-apa (kecuali mencegah cd -dari melakukan sesuatu yang bermanfaat)

Untuk menambahkan direktori baru ke daftar, gunakan pushd dir(atau pushd -n diruntuk menambahkan dir tanpa cd-ing pada saat yang sama)

Anda dapat mengisi ulang pushdtumpukan dengan melakukan sesuatu seperti yang berikut di .bashrcatau ~/.bash_profile:

for d in /var/tmp /tmp /path/to/somewhere/interesting ; do 
  pushd -n "$d" > /dev/null
done

Anda dapat menghapus entri dengan popdatau popd -n.

Lihat help pushd,, help popddan help dirsdalam bash untuk info lebih lanjut. Dan tentu saja man iselect,.

BTW, iselectmungkin tersedia pra-paket untuk distro Anda. Ini untuk Debian dan Ubuntu dll, dan mungkin untuk orang lain juga.

cas
sumber
2

Jika Anda memiliki 5 atau 10 direktori yang sering Anda gunakan, dan tidak perlu peduli dengan direktori 5 atau 10 yang baru digunakan , siapkan beberapa alias perintah seperti

alias cdw="cd /var/www/html" 

Jadi ketika saya ingin pergi ke direktori home page Apache saya cukup ketik cdwseperti yang saya jawab di Equivalent of alias untuk tautan simbolik? .

Mark Stewart
sumber
2

Saya menggunakan lompatan untuk dengan cepat mengubah direktori kerja.

Untuk menambahkan direktori saat ini:

jump -a [bookmark-name]

Untuk membuat daftar semua bookmark Anda:

jump -l

misalnya:

------------------------------------------------------------------
 Bookmark    Path                                                 
------------------------------------------------------------------
 reports     ~/mydir/documents/reports
 projects    ~/documents/projects
 dl          ~/Downloads                     
------------------------------------------------------------------

Sekarang Anda dapat dengan mudah melompat ke direktori lain:

jump reports

Ini mendukung pelengkapan otomatis untuk bash dan zsh.


Sunting (sebagai respons terhadap @Joe): biner jump-bindisimpan /usr/local/bin, dan dengan skrip integrasi bash (di PC saya yang terletak di /var/lib/gems/1.9.1/gems/jump-0.4.1/bash_integration/shell_driver) ia membuat fungsi bash jumpyang memanggil jump-bin.

agold
sumber
Di mana perintah lompat hidup? Saya tidak memilikinya dan tidak segera melihat di mana mendapatkannya.
Joe
2

Saya gunakan aliasuntuk menavigasi. Jika Anda memiliki beberapa direktori yang sering diakses, maka cukup setel alias. Sebagai contoh,

alias e='cd /etc'
alias h='cd /home'
alias al='cd /var/log/apache2/'

Maka sederhananya

e 

akan membawamu ke /etc.

Binatang Keamanan
sumber