Qual è un modo rapido da riga di comando per passare tra più directory per l'amministrazione del sistema?


46

Qual è un modo rapido da riga di comando per passare tra più directory per l'amministrazione del sistema? Voglio dire, posso usare pushd .e popdalternare, ma cosa succede se voglio archiviare multipli e scorrere tra di loro, piuttosto che eliminarli permanentemente dal fondo della pila?


$CDPATHForse?
roaima,

6
oh mio - ho appena saputo cd -dopo aver cercato su Google istigato da questa domanda.
Nacht - Ripristina Monica

@Nacht: Come hai navigato nella struttura dei file prima ??
Loneboat,

1
Fatto cdovunque a mano. È stato doloroso. Tuttavia, ha utilizzato il completamento automatico con il tasto Tab.
Volomike

1
Forse vuoi provare a provare . Estremamente utile quando si salta molto all'interno della stessa coppia di dir.
Rolf,

Risposte:


28

Usa pushde poi i nomi speciali per le directory nel vostro stack delle directory: ~1, ~2, etc.

Esempio:

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 $ 

Il modo più efficace di utilizzare pushdin questo modo è caricare l'elenco delle directory, quindi aggiungere un'altra directory come directory corrente, quindi è possibile saltare tra i numeri statici senza influire sulla posizione delle directory nello stack.


Vale anche la pena notare che cd -ti porterà all'ultima directory in cui ti trovavi. Così farà cd ~-.

Il vantaggio di ~-sopra solo -è che -è specifico per cd, che ~-viene espanso dalla shell stesso modo che ~1, ~2ecc sono. Questo è utile quando si copia un file tra percorsi di directory molto lunghi; per esempio:

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

Quanto sopra equivale a:

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

1
Può anche usarecd -
Volomike

cd -si comporta come un Forth DROP DUP, ad esempio se si inizia con nella directory a , con stack abcd , si cd -cambia lo stack in bbcd . Forse è bashcomunque un bug, poiché un secondo cd -modifica lo stack in abcd . Da ciò possiamo dedurre che cd -utilizza una struttura di dati separata per memorizzare la directory precedente, oltre a modificare lo stack.
agc,

3
@agc, cd -usi $OLDPWDe nient'altro.
Carattere jolly

Quindi forse è cd -stata la prima funzione bash , poi hanno aggiunto uno stack, ma hanno temuto di rompere il vecchio codice più di quanto volessero un design più semplice. Correzione alla precedente, si cd -comporta come un Forth OLDPWD @ SWAP OLDPWD ! DUP . Diversamente cd foo, cd -stampa il nome della directory scambiata.
agc,

Oppure c'è sempre il wrapper pushd interattivo (altre risposte a questa domanda includono autojump ecc. Ecc.).
Inutile

42

bashIl comando incorporato pushdcon le opzioni +e -può ruotare lo stack di directory. La sintassi può essere un po 'confusa, forse perché quello stack è un array a base zero . Queste semplici funzioni di wrapper fanno scorrere lo stack di directory:

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

Test: imposta una pila di quattro directory.

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

Ora / tmp è la directory corrente e lo stack appare come:

/tmp /bin /etc /home

Passa alla directory successiva nello stack, (e mostrala), quattro volte:

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

Produzione:

/bin
/etc
/home
/tmp

Passa alla directory precedente nello stack, (e mostrala), quattro volte:

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

Produzione:

/home
/etc
/bin
/tmp

Una nota su cd -: la risposta di Wildcard ha aiutato a illustrare come cd -non usa l' array $ DIRSTACK (usa la variabile $ OLDPW ), quindi ciò cd -non influisce su $ DIRSTACK come dovrebbe fare uno scambio basato su stack. Per correggerlo, ecco una semplice funzione di swap basata su $ DIRSTACK :

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

Test:

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

Produzione:

/bin /tmp
/etc /bin /tmp
/lib /etc /bin /tmp
/home /lib /etc /bin /tmp
/lib /home /etc /bin /tmp
/home /lib /etc /bin /tmp

La mia frustrazione è che voglio mettere gli oggetti in pila e tenerli lì fino a quando non scelgo di cancellare la pila. In questo modo, posso spingere, spingere, spingere, quindi scorrere ciascuna delle tre directory, se necessario. Supponiamo ad esempio che devo passare da una directory all'altra come se fossero come le schede del browser e andare avanti e indietro, fino a quando non chiudo una scheda. Questo indirizza questo in un modo da riga di comando?
Volomike,

5
Sì, credo di si, provalo. Per rimuovere l'elemento in alto, fare popd, per rimuoverlo senza cambiare directory, fare popd -n. Per cancellare la pila fare dirs -c. Peccato che i designer bash abbiano seppellito funzioni così utili in una sintassi non intuitiva. Vedi man bashsotto pushd, dirsecc.
agc,

Lavori! Ed era chiaro come fango nei documenti. Mi piace la sua semplicità, ora che conosco la tecnica.
Volomike,

13

Ti suggerisco di installare fasd . Ti dà la possibilità di saltare rapidamente a qualsiasi directory in cui sei già stato digitando solo una piccola parte del suo nome.

Esempio: se hai visitato /home/someName/scripts/, puoi saltare lì semplicemente digitando z scrad esempio. È molto più conveniente che ricordare l'ordinamento nello stack della cronologia o qualcosa di simile.


10

Quando cdqualche parte, Bash memorizza la directory di lavoro vecchio una variabile di ambiente, $OLDPWD.

Puoi tornare a quella directory con cd -, che è equivalente a cd "$OLDPWD".

Puoi rimbalzare avanti e indietro tra le directory in questo modo:

blue$ cd ~/green
green$ cd -
blue$ cd -
green$

6

Ho scritto uno script chiamato xyzzyper fare questo:

#!/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

Il modo in cui lo uso è copiare in una /usr/bincartella e poi chmod a+xsu di essa. Quindi, modifico il mio ~/.bashrcfile di account root e utente per includere queste righe in fondo:

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

'Xy' è una forma abbreviata del comando per una digitazione più rapida.

Quindi, posso memorizzare la directory corrente nell'elenco con ...

xyzzy this

... e ripetere se necessario. Una volta riempito questo elenco con le directory di cui ho bisogno, rimangono lì fino a quando non riavvio il computer perché è in quel momento che / tmp viene nuovamente cancellato. Posso quindi digitare ...

xyzzy show

... per elencare le directory attualmente salvate. Per passare a una directory, ho due scelte. Un'opzione è specificare il percorso per indice (ed è un indice basato su 1) in questo modo:

xyzzy 2

... che passerebbe alla directory che è il secondo elemento nell'elenco. Oppure, potrei lasciare il numero di indice e fare semplicemente:

xyzzy

... per farlo scorrere attraverso ogni directory di cui ho bisogno. Per altri comandi che puoi eseguire, digita:

xyzzy help

Naturalmente, il lavoro è più divertente con le sciocche dichiarazioni di eco che ho aggiunto.

Nota che xyzzy è un riferimento all'avventura testuale di Collosal Cave , in cui digitando xyzzy ti permetterebbe di passare da una stanza all'altra per evitare grues.


2
+1 Ho iniziato a giocare con questo. È bello, ma sembra fallire se non sono state ancora aggiunte directory e si immette solo xyzzy. È necessario un altro test per MAXLINES -eq 0 in cyclenext ().
Joe,

5

Uso un piccolo script chiamato z [link] , che potrebbe anche interessare, anche se non fa esattamente quello che mi hai chiesto.

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.

Forse ho perso qualcosa, ma dove trovo lo script z stesso?
Joe,

Siamo spiacenti, il collegamento era sulla z. Modificherà per renderlo più facile da vedere.
Graipher

5

C'è anche cd_funcda Petar Marinov, fondamentalmente cdcon una cronologia di fino a 10 voci: 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

Usare semplicemente cd --per mostrare un elenco delle oltre 10 directory passate cde cd -N(dove si Ntrova l'indice della voce) per andare lì.


4

Uso principalmente ZSH con il profilo oh-my-zsh . È possibile digitare in un terminale la seguente corrispondenza:

# cd /ho

Quindi puoi semplicemente usare le frecce (su e giù) per scorrere tutta la cronologia della shell che mostra solo quelle voci che iniziano con i caratteri sopra. Così, per esempio, se si è andato a /home/morfik/Desktop/e /home/morfik/something/, è possibile passare tra le directory molto veloce. Non importa quante voci hai nella cronologia della shell, ma quando ne hai molte, usa solo un'espressione migliore, cioè cd /home/morfe qui premi le frecce su / giù sulla tua tastiera.

C'è anche un altro modo per ottenere la soluzione. In questo caso devi usare tmux e FZF . Quindi fai solo un tasto di scelta rapida, ad esempio ctrl-r, e quando lo premi, la finestra corrente verrà divisa e vedrai questo:

inserisci qui la descrizione dell'immagine

Ora puoi usare le espressioni per cercare l'elenco. Ho appena digitato ^cd /media, che restituisce solo le voci che iniziano con la frase. Naturalmente, puoi semplicemente digitare 'cd 'homeper abbinare il comando e anche l'intero nome della directory (non percorso, solo nome):

inserisci qui la descrizione dell'immagine


4

Puoi raggiungerlo con un mucchio di alias nel tuo ~/.bashrc(o equivalente)

L'obiettivo principale è digitare quasi il minimo (ad esempio, d5saltare alla directory numero 5 nel pool) per passare da una directory all'altra nel pool. Inoltre vogliamo semplificare l'aggiunta / rimozione di directory da / verso il pool:

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

Ora ogni volta che si preme una directory nello stack, questa viene aggiunta al pool numerato nella posizione 0 (la directory corrente) e si può saltare (cambiare directory) usando pochissimo digitando ( d<N>) e si può visualizzare il pool corrente numerato in qualsiasi tempo semplicemente digitando d.

Alcuni esempi di utilizzo di questi alias:

Visualizza il dir-pool numerato, (la directory corrente è # 0)

$ d
 0  /tmp
 1  /
 2  /usr

Passa da una direzione all'altra: usa d<N>

$ d2
$ pwd
/usr

Aggiungi una nuova directory al pool

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

Salta ancora un po ':

$ d3
$ pwd
/

$ d3
$ pwd
/tmp

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

Rimuovere / pop la directory superiore (corrente) dal pool

$ po
$ d
 0  /
 1  /var/log
 2  /usr

2

Se hai installato iselect , potresti fare qualcosa del genere:

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

Questo ti darà un menu navigabile interattivo con tasto freccia interattivo basato su ncurses per selezionare una directory in cui cdandare.

Se non hai utilizzato pushdla sessione shell corrente, l'elenco delle directory nel menu inizia con una sola voce, la directory corrente. Se c'è solo una voce, questo dirselectalias lo farà solo cdsenza la schermata del menu, quindi effettivamente non fa nulla (tranne impedire cd -di fare qualcosa di utile)

Per aggiungere una nuova directory all'elenco, utilizzare pushd dir(o pushd -n dirper aggiungere una directory senza cd-ing allo stesso tempo)

Puoi precompilare lo pushdstack eseguendo una delle seguenti operazioni nel tuo .bashrco ~/.bash_profile:

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

È possibile rimuovere le voci con popdo popd -n.

Vedi help pushd, help popde help dirsin bash per maggiori informazioni. E, naturalmente, man iselect.

A proposito, iselectè probabilmente disponibile pre-confezionato per la tua distribuzione. È per Debian, Ubuntu ecc. E probabilmente anche per altri.


2

Se hai 5 o 10 directory che usi molto e non ti preoccupi necessariamente delle directory 5 o 10 usate di recente , imposta alcuni alias di comando come

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

E quindi quando voglio andare alla directory della home page di Apache, digito cdwcome ho risposto in Equivalente di alias per un collegamento simbolico? .


2

Sto usando il salto per cambiare rapidamente la directory di lavoro.

Per aggiungere la directory corrente:

jump -a [bookmark-name]

Per elencare tutti i tuoi segnalibri:

jump -l

per esempio:

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

Ora puoi passare facilmente a un'altra directory:

jump reports

Supporta il completamento automatico per bash e zsh.


Modifica (in risposta a @Joe): il file binario jump-binè archiviato /usr/local/bine con lo script di integrazione bash (nel mio PC situato in /var/lib/gems/1.9.1/gems/jump-0.4.1/bash_integration/shell_driver) crea una funzione bash jumpche chiama jump-bin.


Dove vive il comando di salto? Non ce l'ho e non vedo immediatamente dove trovarlo.
Joe,

2

Uso aliasper navigare. Se si dispone di poche directory a cui si accede frequentemente, impostare semplicemente gli alias. Per esempio,

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

Quindi semplicemente

e 

ti porterà a /etc.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.