Qu'est-ce qu'un moyen rapide en ligne de commande pour basculer entre plusieurs annuaires pour l'administration système?

46

Qu'est-ce qu'un moyen rapide en ligne de commande pour basculer entre plusieurs annuaires pour l'administration système? Je veux dire, je peux utiliser pushd .et popdbasculer, mais que se passe-t-il si je veux stocker des multiples et les parcourir, plutôt que de les supprimer en permanence du bas de la pile?

Volomike
la source
$CDPATHpeut-être
Roaima
6
oh mon - je viens d'apprendre à propos cd -après googler de cette question.
Nacht - Rétablir Monica
@Nacht: Comment avez-vous navigué dans la structure de fichier avant ??
Loneboat
1
Fait cdpartout à la main. Était douloureux. Complétion automatique utilisée avec la touche de tabulation, cependant.
Volomike
1
Peut-être que vous voulez essayer za . Extrêmement pratique lorsque vous sautez beaucoup dans les mêmes répertoires.
Rolf

Réponses:

28

Utilisez pushdpuis les noms spéciaux pour les répertoires dans votre pile de répertoire: ~1, ~2, etc.

Exemple:

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 $ 

Le moyen le plus efficace pushdconsiste à charger votre liste de répertoires, puis à ajouter un autre répertoire pour qu'il soit votre répertoire actuel. Vous pouvez ensuite naviguer entre les numéros statiques sans affecter la position des répertoires dans votre pile.


Il est également intéressant de noter que cd -vous mènera au dernier répertoire où vous étiez. Il en sera cd ~-.

L'avantage de ~-plus juste -est que -est spécifique cd, alors ~-est élargi par votre coquille de la même manière que ~1, ~2etc. sont. Cela s'avère pratique lors de la copie d'un fichier entre des chemins de répertoire très longs. par exemple:

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

Ce qui précède est équivalent à:

cp /another/long/path/to/where/the/source/file/is/myfile /very/long/path/to/some/directory/
Wildcard
la source
1
Peut également utilisercd -
Volomike
cd -agit comme un Forth DROP DUP, par exemple si on commence par dans le répertoire a , avec la pile abcd , a cd -change la pile en bbcd . Peut-être que c'est un bashbug cependant, puisqu'un deuxième cd -change la pile en abcd . Nous pouvons en déduire que cd -, outre le changement de pile, une structure de données distincte est utilisée pour stocker le répertoire précédent.
agc
3
@Agc, cd -utilise $OLDPWDet rien d'autre.
Wildcard
Alors peut-être que cd -la fonctionnalité bash était antérieure , puis plus tard, ils ont ajouté une pile, mais craignaient de casser l'ancien code plus qu'ils ne souhaitaient une conception plus simple. Correction à la précédente, cd -agit comme un Forth OLDPWD @ SWAP OLDPWD ! DUP . Contrairement à cd foo, cd -affiche le nom du répertoire swappé.
agc
Ou bien il y a toujours l' encapsuleur pushd interactif (les autres réponses à cette question incluent autojump, etc., etc.).
Inutile
42

bashLa fonction intégrée pushdavec les options +et -peut faire pivoter la pile de répertoires. La syntaxe peut être un peu déroutante, peut-être parce que cette pile est un tableau de base zéro . Ces fonctions d'encapsulation simples parcourent la pile de répertoires:

# 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: configurez une pile de quatre répertoires.

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

Maintenant, / tmp est le répertoire actuel et la pile ressemble à ceci:

/tmp /bin /etc /home

Passez au répertoire suivant de la pile (et montrez-le), quatre fois:

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

Sortie:

/bin
/etc
/home
/tmp

Passer au répertoire précédent dans la pile (et le montrer), quatre fois:

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

Sortie:

/home
/etc
/bin
/tmp

Une remarque sur cd -: La réponse de Wildcard a permis d'illustrer comment cd -ne pas utiliser le tableau $ DIRSTACK (il utilise la variable $ OLDPW ), de sorte que cela cd -n'a pas d'effet sur $ DIRSTACK comme un swap basé sur une pile. Pour corriger cela, voici une simple fonction d' échange basée sur $ DIRSTACK :

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

Tester:

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

Sortie:

/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
la source
Ma frustration est que je veux mettre des éléments dans la pile et les conserver jusqu'à ce que je décide de vider la pile. De cette façon, je peux pousser, pousser, pousser, puis parcourir chacun des trois répertoires selon les besoins. Supposons, par exemple, que j’ai besoin de basculer entre trois répertoires comme s’ils ressemblent à des onglets de navigateur et d’aller et venir jusqu’à ce que je ferme un onglet. Est-ce que ceci adresse ceci d'une manière de ligne de commande?
Volomike
5
Oui, je le crois, essayez-le. Pour supprimer l'élément du haut, faites-le popd, pour le supprimer sans changer de répertoire, faites-le popd -n. Pour vider la pile, faites dirs -c. Dommage que les concepteurs bash aient enterré de telles fonctions utiles dans une syntaxe non intuitive. Voir ci- man bashdessous pushd, dirsetc.
agc
Travaux! Et était clair comme de la boue dans les docs. J'aime la simplicité, maintenant que je connais la technique.
Volomike
13

Je vous suggère d'installer FASD . Il vous permet d’accéder rapidement à tout répertoire dans lequel vous vous êtes déjà trouvé en ne tapant qu’une petite fraction de son nom.

Exemple: si vous avez visité le site /home/someName/scripts/, vous pouvez y accéder simplement en tapant z scrpar exemple. Il est bien plus pratique que de rappeler l'ordre dans la pile d'historique ou quelque chose de similaire.

kaqqao
la source
10

Lorsque vous cdquelque part, Bash magasins l'ancien répertoire de travail une variable d'environnement, $OLDPWD.

Vous pouvez revenir à ce répertoire avec cd -, ce qui équivaut à cd "$OLDPWD".

Vous pouvez naviguer entre les répertoires comme ceci:

blue$ cd ~/green
green$ cd -
blue$ cd -
green$
RJHunter
la source
6

J'ai écrit un script nommé xyzzypour faire ceci:

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

La façon dont j'utilise ceci est de copier dans un /usr/bindossier et ensuite chmod a+xdessus. Ensuite, je modifie mes ~/.bashrcfichiers de compte utilisateur et racine pour inclure ces lignes en bas:

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

Le «xy» est une forme abrégée de la commande permettant une saisie plus rapide.

Ensuite, je peux stocker le répertoire actuel dans la liste avec ...

xyzzy this

... et répétez si nécessaire. Une fois que je remplis cette liste avec les répertoires dont j'ai besoin, ils y restent jusqu'à ce que je redémarre l'ordinateur car c'est à ce moment que / tmp est effacé. Je peux alors taper ...

xyzzy show

... pour lister les répertoires actuellement enregistrés. Afin de passer à un répertoire, j'ai deux choix. Une option consiste à spécifier le chemin par index (et c'est un index basé sur 1) comme suit:

xyzzy 2

... qui basculerait vers le répertoire qui est le deuxième élément de la liste. Ou, je pourrais laisser le numéro d'index et juste faire:

xyzzy

... de le faire parcourir chaque répertoire selon mes besoins. Pour plus de commandes que vous pouvez faire, tapez:

xyzzy help

Bien sûr, le travail est plus amusant avec les déclarations d'écho stupides que j'ai ajoutées.

Notez que xyzzy est une référence à l’ aventure textuelle de Collosal Cave , où taper xyzzy vous permet de basculer entre deux salles du jeu afin d’éviter les grues.

Volomike
la source
2
+1 j'ai commencé à jouer avec ça. C'est bien, mais cela semble échouer si aucun répertoire n'a encore été ajouté et que vous entrez simplement xyzzy. Nécessite un test supplémentaire pour MAXLINES -eq 0 dans cyclenext ().
Joe
5

J'utilise un petit script appelé z [lien] , qui pourrait également être intéressant, même s'il ne fait pas exactement ce que vous avez demandé.

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
la source
J'ai peut-être manqué quelque chose, mais où puis-je trouver le script z lui-même?
Joe
Désolé, le lien était sur le z. Va éditer pour le rendre plus facile à voir.
Graipher
5

Il y a aussi cd_funcde Petar Marinov, il a en gros cdun historique de 10 entrées: 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

Utilisez simplement cd --pour afficher une liste des 10 derniers répertoires que vous avez édités cdet cd -N(où Nest l’index de l’entrée) pour y aller.

phk
la source
4

J'utilise principalement ZSH avec le profil oh-my-zsh . Vous pouvez taper dans un terminal la correspondance suivante:

# cd /ho

Ensuite, vous pouvez simplement utiliser les flèches (haut et bas) pour parcourir tout l'historique du shell, qui ne montre que les entrées commençant par les caractères ci-dessus. Ainsi, par exemple, si vous êtes allé sur /home/morfik/Desktop/et /home/morfik/something/, vous pouvez basculer très rapidement d'un répertoire à l'autre. Peu importe le nombre d'entrées que vous avez dans l'historique du shell, mais lorsque vous en avez beaucoup, utilisez simplement une meilleure expression, c'est cd /home/morf-à- dire et appuyez ici sur les flèches haut / bas de votre clavier.

Il existe également un autre moyen de parvenir à la solution. Dans ce cas, vous devez utiliser tmux et FZF . Ensuite, vous créez simplement un raccourci clavier, par exemple ctrl-r, et lorsque vous appuyez dessus, votre fenêtre actuelle sera divisée et vous verrez ceci:

entrez la description de l'image ici

Vous pouvez maintenant utiliser des expressions pour effectuer une recherche dans la liste. Je viens de taper ^cd /media, ce qui ne retourne que les entrées qui commencent par la phrase. Bien sûr, vous pouvez simplement taper 'cd 'homepour faire correspondre la commande et également le nom du répertoire complet (pas le chemin, juste le nom):

entrez la description de l'image ici

Mikhail Morfikov
la source
4

Vous pouvez y arriver avec un tas de pseudonymes dans votre ~/.bashrc(ou équivalent)

L'objectif principal est de taper au minimum (par exemple, d5passer au répertoire numéro 5 du pool) pour basculer entre les répertoires du pool. Nous souhaitons également faciliter l'ajout / la suppression de répertoires au / du 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

Maintenant, chaque fois que vous poussez un répertoire sur la pile, il est ajouté au pool numéroté à la position 0 (répertoire actuel) et vous pouvez sauter (changer de répertoire) en utilisant très peu de frappe ( d<N>) et vous pouvez afficher votre pool actuel numéroté à tout moment. le temps en tapant simplement d.

Quelques exemples d'utilisation de ces alias:

Affiche le répertoire numéroté, (le répertoire actuel est # 0)

$ d
 0  /tmp
 1  /
 2  /usr

Basculer entre les répertoires: utiliser d<N>

$ d2
$ pwd
/usr

Ajouter un nouveau répertoire au pool

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

Sauter un peu plus:

$ d3
$ pwd
/

$ d3
$ pwd
/tmp

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

Supprimer / extraire le premier répertoire (actuel) du pool

$ po
$ d
 0  /
 1  /var/log
 2  /usr
arielf
la source
2

Si vous avez installé iselect , vous pouvez faire quelque chose comme ceci:

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

Cela vous donnera un menu navigable interactif à touches fléchées basé sur ncurses en plein écran pour sélectionner un répertoire cd.

Si vous n'avez pas utilisé pushdla session actuelle du shell, la liste des répertoires du menu commence par une seule entrée, votre répertoire actuel. S'il n'y a qu'une entrée, cet dirselectalias le sera cdsans l'écran du menu, de sorte qu'il ne fait rien (sauf empêcher cd -de faire quoi que ce soit d'utile)

Pour ajouter un nouveau répertoire à la liste, utilisez pushd dir(ou pushd -n dirpour ajouter un répertoire sans le cdmodifier en même temps)

Vous pouvez pré-renseigner la pushdpile en procédant comme suit dans votre .bashrcou ~/.bash_profile:

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

Vous pouvez supprimer des entrées avec popdou popd -n.

Voir help pushd, help popdet help dirsen bash pour plus d'informations. Et bien sur man iselect.

BTW, iselectest probablement disponible pré-emballé pour votre distribution. C'est pour Debian et Ubuntu, etc., et probablement aussi pour d'autres.

cas
la source
2

Si vous utilisez 5 ou 10 répertoires et que vous ne vous souciez pas nécessairement des 5 ou 10 répertoires récemment utilisés , configurez des alias de commande tels que

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

Et donc, lorsque je veux aller au répertoire de la page d'accueil Apache, je tape simplement cdwcomme j'ai répondu dans l' équivalent d'un alias pour un lien symbolique? .

Mark Stewart
la source
2

J'utilise jump pour changer rapidement le répertoire de travail.

Pour ajouter le répertoire actuel:

jump -a [bookmark-name]

Pour lister tous vos favoris:

jump -l

par exemple:

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

Maintenant, vous pouvez facilement accéder à un autre répertoire:

jump reports

Il supporte l'auto-complétion pour bash et zsh.


Edit (en réponse à @Joe): le binaire jump-binest stocké dans /usr/local/bin, et avec le script d’intégration bash (sur mon PC situé sur /var/lib/gems/1.9.1/gems/jump-0.4.1/bash_integration/shell_driver), il crée une fonction bash jumpqui appelle jump-bin.

agold
la source
Où la commande de saut vit-elle? Je ne l'ai pas et ne vois pas immédiatement où l'obtenir.
Joe
2

J'utilise aliaspour naviguer. Si vous avez peu de répertoires fréquemment consultés, définissez simplement des alias. Par exemple,

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

Alors simplement

e 

va vous emmener à /etc.

Bête de sécurité
la source