Was ist eine schnelle Befehlszeilenmethode zum Wechseln zwischen mehreren Verzeichnissen für die Systemadministration?

46

Was ist eine schnelle Befehlszeilenmethode zum Wechseln zwischen mehreren Verzeichnissen für die Systemadministration? Ich meine, ich kann pushd .und popdzum Umschalten verwenden, aber was ist, wenn ich Mehrfachwerte speichern und durch sie blättern möchte, anstatt sie permanent vom Boden des Stapels zu werfen?

Volomike
quelle
$CDPATHvielleicht?
Roaima
6
Oh mein cd -Gott, ich habe es erst erfahren, nachdem das Googeln durch diese Frage ausgelöst wurde.
Nacht - Reinstate Monica
@Nacht: Wie hast du die Dateistruktur vorher navigiert ???
Loneboat
1
Hat cdüberall von Hand. War schmerzhaft. Automatische Vervollständigung mit der Tabulatortaste.
Volomike
1
Vielleicht möchten Sie za versuchen . Sehr praktisch, wenn Sie innerhalb eines Verzeichnisses viel herumspringen.
Rolf

Antworten:

28

Verwenden pushdund dann die speziellen Namen für die Verzeichnisse in Ihrem Verzeichnis - Stack: ~1, ~2usw.

Beispiel:

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 $ 

Auf pushddiese Weise können Sie am effektivsten Ihre Verzeichnisliste laden und dann ein weiteres Verzeichnis als aktuelles Verzeichnis hinzufügen. Anschließend können Sie zwischen den statischen Zahlen wechseln, ohne die Position der Verzeichnisse in Ihrem Stapel zu beeinflussen.


Es ist auch erwähnenswert, dass cd -Sie zum letzten Verzeichnis nehmen Sie in waren. Also wird cd ~-.

Der Vorteil von ~-over just -ist, dass er -spezifisch ist cd, wohingegen er von Ihrer Shell auf die gleiche Weise ~-erweitert wird~1 , wie es bei ~2, usw. der Fall ist. Dies ist praktisch, wenn Sie eine Datei zwischen sehr langen Verzeichnispfaden kopieren. z.B:

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

Das obige ist äquivalent zu:

cp /another/long/path/to/where/the/source/file/is/myfile /very/long/path/to/some/directory/
Platzhalter
quelle
1
Kann auch verwendencd -
Volomike
cd -verhält sich wie ein Forth DROP DUP, wenn man zB mit stack abcd in Verzeichnis a beginnt , cd -ändert a den Stack in bbcd . Vielleicht ist das jedoch ein bashFehler, da eine Sekunde cd -den Stack zurück auf abcd ändert . Daraus können wir schließen, dass cd -zusätzlich zum Ändern des Stacks eine separate Datenstruktur zum Speichern des vorherigen Verzeichnisses verwendet wird.
agc
3
@agc, cd -benutzt $OLDPWDund sonst nichts.
Wildcard
Vielleicht cd -war es die frühere Bash- Funktion, dann später fügten sie einen Stapel hinzu, befürchteten jedoch, den alten Code mehr zu brechen, als sie sich ein einfacheres Design wünschten. Korrektur zum vorherigen, cd -verhält sich wie ein Forth OLDPWD @ SWAP OLDPWD ! DUP . Im Gegensatz cd foozum cd -druckt das den Namen des eingelagerten Verzeichnisses.
agc
Oder es gibt immer den interaktiven Pushd-Wrapper (andere Antworten auf diese Frage beinhalten Autojump usw. usw.).
Useless
42

bash‚s builtin pushdmit den +und -Optionen können die Verzeichnis - Stack drehen. Die Syntax kann etwas verwirrend, vielleicht, weil die Stapel a ist Null -Basis - Array. Diese einfachen Wrapper-Funktionen durchlaufen den Verzeichnis-Stack:

# 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: Richten Sie einen Stapel von vier Verzeichnissen ein.

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

Jetzt ist / tmp das aktuelle Verzeichnis und der Stack sieht folgendermaßen aus:

/tmp /bin /etc /home

Wechseln Sie viermal in das nächste Verzeichnis im Stapel (und zeigen Sie es an):

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

Ausgabe:

/bin
/etc
/home
/tmp

Wechseln Sie viermal in das vorherige Verzeichnis im Stapel (und zeigen Sie es an):

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

Ausgabe:

/home
/etc
/bin
/tmp

Ein Hinweis zu cd -: Die Antwort von Wildcard hat gezeigt , wie cd -das Array $ DIRSTACK nicht verwendet wird (es verwendet die Variable $ OLDPW ), sodass cd -sich $ DIRSTACK nicht wie bei einem stapelbasierten Swap auswirkt . Zu korrigieren , dass hier eine einfachen $ DIRSTACK -basierte Swap - Funktion:

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

Prüfung:

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

Ausgabe:

/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
quelle
Meine Frustration ist, dass ich Gegenstände in den Stapel legen und dort belassen möchte, bis ich mich entscheide, den Stapel zu leeren. Auf diese Weise kann ich drücken, drücken, drücken und je nach Bedarf durch drei Verzeichnisse fahren. Angenommen, ich muss zwischen drei Verzeichnissen wechseln, als ob sie Browser-Registerkarten gleichen, und hin und her gehen, bis ich eine Registerkarte schließe. Wird dies in einer Befehlszeile angesprochen?
Volomike
5
Ja, ich glaube schon, probiere es aus. Um das oberste Element popdzu entfernen , tun Sie , um es zu entfernen, ohne die Verzeichnisse zu ändern popd -n. Um den Stapel zu löschen, machen Sie dirs -c. Schade, dass die Bash- Designer solche nützlichen Funktionen in nicht-intuitiver Syntax versteckt haben. Siehe man bashunter pushd, dirsusw.
agc
Funktioniert! Und war klar wie Schlamm in den Dokumenten. Ich mag die Einfachheit, jetzt wo ich die Technik kenne.
Volomike
13

Ich schlage vor, dass Sie fasd installieren . Es gibt Ihnen die Möglichkeit, schnell zu jedem Verzeichnis zu springen, in dem Sie bereits waren, indem Sie nur einen kleinen Bruchteil seines Namens eingeben.

Beispiel: Wenn Sie besucht haben /home/someName/scripts/, können Sie dorthin springen, indem Sie beispielsweise Folgendes eingeben z scr. Es ist weitaus bequemer, sich die Reihenfolge im Verlaufsstapel oder Ähnliches zu merken.

kaqqao
quelle
10

Wenn Sie cdirgendwo sind, speichert Bash das alte Arbeitsverzeichnis als Umgebungsvariable $OLDPWD.

Sie können mit zu dem Verzeichnis zurückkehren cd -, das dem entspricht cd "$OLDPWD".

Sie können wie folgt zwischen Verzeichnissen wechseln:

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

Ich habe ein Skript namens geschrieben xyzzy, um dies zu tun:

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

Die Art und Weise, wie ich das benutze, ist es, in einen /usr/binOrdner zu kopieren und dann chmod a+xdarauf. Anschließend bearbeite ich meine Stamm- und Benutzerkontodatei so ~/.bashrc, dass die folgenden Zeilen unten angezeigt werden:

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

Das 'xy' ist eine Kurzform des Befehls zum schnelleren Tippen.

Dann kann ich das aktuelle Verzeichnis in der Liste speichern mit ...

xyzzy this

... und bei Bedarf wiederholen. Sobald ich diese Liste mit den benötigten Verzeichnissen gefüllt habe, bleiben sie dort, bis ich den Computer neu starte, da dann / tmp wieder gelöscht wird. Ich kann dann tippen ...

xyzzy show

... um die aktuell gespeicherten Verzeichnisse aufzulisten. Um in ein Verzeichnis zu wechseln, habe ich zwei Möglichkeiten. Eine Möglichkeit besteht darin, den Pfad nach Index anzugeben (und es handelt sich um einen 1-basierten Index):

xyzzy 2

... das zu dem Verzeichnis wechseln würde, das das zweite Element in der Liste ist. Oder ich könnte die Indexnummer weglassen und einfach tun:

xyzzy

... damit es jedes Verzeichnis nach Bedarf durchläuft. Für weitere Befehle, die Sie ausführen können, geben Sie Folgendes ein:

xyzzy help

Natürlich macht die Arbeit mit den albernen Echoanweisungen, die ich hinzugefügt habe, mehr Spaß.

Beachten Sie, dass xyzzy eine Referenz zum Textabenteuer Collosal Cave ist , bei dem Sie durch Eingabe von xyzzy zwischen zwei Räumen im Spiel wechseln können, um Grausamkeiten zu vermeiden.

Volomike
quelle
2
+1 Ich habe damit angefangen zu spielen. Es ist schön, aber scheint zu scheitern, wenn noch keine Verzeichnisse hinzugefügt wurden und Sie nur xyzzy eingeben. Benötigt noch einen Test für MAXLINES -eq 0 in cyclenext ().
Joe
5

Ich verwende ein kleines Skript namens z [link] , das ebenfalls von Interesse sein könnte, obwohl es nicht genau das tut, was Sie gefragt haben.

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
quelle
Vielleicht habe ich etwas verpasst, aber wo finde ich das Z-Skript selbst?
Joe
Sorry, der Link war auf der z. Wird bearbeitet, um die Anzeige zu erleichtern.
Graipher
5

Es gibt auch cd_funcvon Petar Marinov, es ist im Grunde cdmit einer Geschichte von bis zu 10 Einträgen: 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

Verwenden Sie einfach cd --, um eine Liste der letzten 10 Verzeichnisse anzuzeigen, in die Sie gegangen sind cd, und cd -N(wo Nist der Index des Eintrags), um dorthin zu gelangen.

phk
quelle
4

Ich benutze meistens ZSH mit oh-my-zsh Profil. Sie können die folgende Übereinstimmung in ein Terminal eingeben:

# cd /ho

Dann können Sie einfach die Pfeile (nach oben und nach unten) verwenden, um den gesamten Shell-Verlauf durchzugehen, in dem nur die Einträge angezeigt werden, die mit den obigen Zeichen beginnen. Wenn Sie zum Beispiel zu /home/morfik/Desktop/und gegangen sind /home/morfik/something/, können Sie sehr schnell zwischen den Verzeichnissen wechseln. Es spielt keine Rolle, wie viele Einträge Sie im Shell-Verlauf haben, aber wenn Sie viel haben, verwenden Sie einfach einen besseren Ausdruck, dh cd /home/morfund drücken Sie hier die Auf- / Ab-Pfeiltasten auf Ihrer Tastatur.

Es gibt auch einen anderen Weg, um die Lösung zu erreichen. In diesem Fall müssen Sie verwenden tmux und FZF . Dann machen Sie einfach einen Hotkey, zum Beispiel Strg-R, und wenn Sie ihn drücken, wird Ihr aktuelles Fenster geteilt und Sie werden folgendes sehen:

Bildbeschreibung hier eingeben

Jetzt können Sie Ausdrücke verwenden, um die Liste zu durchsuchen. Ich habe gerade getippt ^cd /media, was nur die Einträge zurückgibt, die mit der Phrase beginnen. Natürlich können Sie einfach eingeben 'cd 'home, um den Befehl und auch den gesamten Verzeichnisnamen (nicht Pfad, nur Name) abzugleichen:

Bildbeschreibung hier eingeben

Mikhail Morfikov
quelle
4

Sie können dies mit einer Reihe von Aliasen in Ihrem ~/.bashrc(oder einem gleichwertigen)

Das Hauptziel ist eine möglichst minimale Eingabe (z. B. d5Springen zu Verzeichnisnummer 5 im Pool), um zwischen den Verzeichnissen im Pool zu wechseln. Außerdem möchten wir das Hinzufügen / Entfernen von Verzeichnissen zu / aus dem Pool vereinfachen:

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

Jetzt wird jedes Mal, wenn Sie ein Verzeichnis auf dem Stapel verschieben, es an Position 0 (das aktuelle Verzeichnis) zum nummerierten Pool hinzugefügt, und Sie können mit sehr wenig Eingabe ( d<N>) herumspringen (Verzeichnisse wechseln ) und Ihren nummerierten aktuellen Pool an jedem beliebigen Ort anzeigen Zeit, indem Sie nur tippen d.

Einige Beispiele für die Verwendung dieser Aliase:

Anzeigen des nummerierten Verzeichnispools (aktuelles Verzeichnis ist # 0)

$ d
 0  /tmp
 1  /
 2  /usr

Wechsle zwischen den Verzeichnissen: benutze d<N>

$ d2
$ pwd
/usr

Fügen Sie dem Pool ein neues Verzeichnis hinzu

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

Springe noch ein bisschen herum:

$ d3
$ pwd
/

$ d3
$ pwd
/tmp

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

Entfernen Sie das oberste (aktuelle) Verzeichnis aus dem Pool

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

Wenn Sie iselect installiert haben, können Sie Folgendes tun:

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

Dies gibt Ihnen ein Vollbild-ncurses-basiertes interaktives Menü mit Pfeiltasten, in dem Sie ein Verzeichnis auswählen können, cdzu dem Sie wechseln möchten .

Wenn Sie pushdin der aktuellen Shell-Sitzung nicht verwendet haben , beginnt die Liste der Verzeichnisse im Menü mit nur einem Eintrag, Ihrem aktuellen Verzeichnis. Wenn nur ein Eintrag vorhanden ist, wird dieser dirselectAlias ​​nur cdohne den Menübildschirm verwendet, sodass cd -praktisch nichts ausgeführt wird (außer, dass keine nützlichen Aktionen ausgeführt werden).

Um der Liste ein neues Verzeichnis hinzuzufügen, verwenden Sie pushd dir(oder pushd -n dir, um ein Verzeichnis hinzuzufügen, ohne cdes gleichzeitig mit-zu versehen).

Sie können den pushdStapel vorab füllen, indem Sie in Ihrem .bashrcoder folgendermaßen vorgehen ~/.bash_profile:

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

Sie können Einträge mit popdoder entfernen popd -n.

Weitere Informationen finden Sie help pushdunter help popd, und help dirsin der Bash. Und natürlich man iselect.

Übrigens iselectist wahrscheinlich für Ihre Distribution vorverpackt. Es ist für Debian und Ubuntu usw. und wahrscheinlich auch für andere.

cas
quelle
2

Wenn Sie 5 oder 10 Verzeichnisse haben, die Sie häufig verwenden, und sich nicht unbedingt für kürzlich verwendete 5 oder 10 Verzeichnisse interessieren , richten Sie einige Befehls-Aliase wie ein

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

Und wenn ich zum Apache-Homepageverzeichnis gehen möchte, gebe ich einfach ein, cdwwie ich unter Entsprechung des Alias ​​für einen symbolischen Link geantwortet habe ? .

Mark Stewart
quelle
2

Ich benutze Sprung , um das Arbeitsverzeichnis schnell zu ändern.

So fügen Sie das aktuelle Verzeichnis hinzu:

jump -a [bookmark-name]

So listen Sie alle Ihre Lesezeichen auf:

jump -l

z.B:

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

Jetzt können Sie ganz einfach in ein anderes Verzeichnis springen:

jump reports

Es unterstützt die automatische Vervollständigung für bash und zsh.


Bearbeiten (als Antwort auf @Joe): Die Binärdatei jump-binwird in gespeichert /usr/local/binund erstellt mit dem Bash-Integrationsskript (auf meinem PC unter /var/lib/gems/1.9.1/gems/jump-0.4.1/bash_integration/shell_driver) eine Bash-Funktion, jumpdie aufruft jump-bin.

ein Gold
quelle
Wo wohnt der Sprungbefehl? Ich habe es nicht und sehe nicht sofort, wo ich es bekommen kann.
Joe
2

Ich benutze, um aliaszu navigieren. Wenn Sie nur wenige Verzeichnisse haben, auf die häufig zugegriffen wird, legen Sie einfach Aliase fest. Zum Beispiel,

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

Dann einfach

e 

bringt dich zu /etc.

Sicherheitstier
quelle