Journal Des bookmarks dans mon terminal !

Posté par . Licence CC by-sa
20
9
jan.
2015

Coucou à tous !

Je voulais vous partager une astuce toute simple que je viens de mettre en place sur mon ordi, en espérant que ça puisse servir à d'autre.

Il m'arrive régulièrement d'avoir simultanément plusieurs dossiers de travail en console, et je voulais pouvoir passer facilement de l'un à l'autre en console. Je me suis donc créé deux commandes shell : x et ccd. Je les ai appelé comme ça par ce que je manquait d'inspiration, que x c'est cour, et que ccd ça ressemble à cd, et que c'est ’dredi :) L'installation est très simple : copier-coller le code suivant dans votre ~/.truc-chose-shell-rc. On peut bien sur tout mettre sur deux lignes, mais je me suis dis que ça serais plus écrit compréhensible comme ça :

function ccd() {
    if [ -r ~/.signet/save$1 ]
    then
        cd "$(cat ~/.signet/save$1)"
    else
        echo >&2 "Le signet $1 n'existe pas"
    fi
}

function x() {
    pwd > ~/.signet/save$1
    pwd > ~/.signet/save
}

Pour les plus mauvais en shell, voici comment s'en servir :

Concrètement la commande x sans argument sauve le dossier courant dans un fichier, ce qui me permet d'y revenir plus tard avec la commande ccd. Si j'ajoute une argument, par exemple x signet1 alors ccd signet1 me permettra de crée un signet nommé, et me permettre d'y revenir plus tard avec ccd signet1. Bonus sur la cerise : vu que les signets sont sauvés dans des fichiers, alors, ils sont persistant au reboot. NB : ccd sans arguments permet toujours d'aller dans le dernier dossier enregistré (avec ou sans signet nommé).

Voila, c'est tout. Certes ce n'est pas grand chose, et la plus part d'entre vous savent faire bien mieux que moi, mais je pensais que ça valais la peine d'être partagé. Le shell n'étant pas du tout ma spécialité, je suis ouvert à toutes critiques.

Et vous, vous avez d'autres astuces que vous utilisez tous les jours à partager ?

  • # ça existait déjà

    Posté par . Évalué à 7.

    En tout cas dans bash :

    $ help pushd
    pushd: pushd [-n] [+N | -N | rép]
        Ajoute un répertoire à la pile.
    
        Ajoute un répertoire en haut de la pile des répertoires, ou permute
        la pile, de façon que le répertoire en haut de la pile devienne
        le nouveau répertoire de travail. S'il n'y a pas d'argument, les deux
        répertoires en haut de la pile sont échangés.
    
        Options :
        -n  ne pas changer de répertoire de travail lorsque des répertoires
            sont ajoutés à la pile, de façon que seule la pile soit manipulée
    
        Arguments :
        +N  Permuter la pile de façon que le Nième répertoire se place en haut,
            en comptant de zéro depuis la gauche de la liste fournie par « dirs ».
    
        -N  Permuter la pile de façon que le Nième répertoire se place en haut,
            en comptant de zéro depuis la droite de la liste fournie par « dirs ».
    
        dir ajouter le répertoire DIR en haut de la pile, et en faire le nouveau
            répertoire de travail.
    
        Vous pouvez voir la pile des répertoires avec la commande « dirs ».
    
        Code de sortie :
        Renvoie le code de succès à moins qu'un argument non valable ne soit fourni
        ou que le changement de répertoire n'échoue.
    $ help popd
    popd: popd [-n] [+N | -N]
        Enlève des répertoires de la pile.
    
        Enlève des éléments de la pile des répertoires. S'il n'y a pas
        d'argument, le répertoire en haut de la pile est enlevé,
        et le nouveau sommet de la pile devient le répertoire de travail.
    
        Options :
        -n  ne change pas de répertoire de travail lorsque des répertoires
            sont enlevés de la pile, de façon que seule la pile soit manipulée
    
        Arguments :
        +N  Enlève le Nième répertoire, en comptant de zéro depuis la gauche
            de la liste fournie par « dirs ». Par exemple : « popd +0 »
            enlève le premier répertoire, « popd +1 » le deuxième.    
        -N  Enlève le Nième répertoire, en comptant de zéro depuis la droite
            de la liste fournie par « dirs ». Par exemple : « popd -0 »
            enlève le dernier répertoire, « popd -1 » l'avant-dernier.
        Vous pouvez voir la pile des répertoires avec la commande « dirs ».
    
        Code de sortie :
        Renvoie le code de succès à moins qu'un argument non valable ne soit donné
        ou que le changement de répertoire n'échoue.
    

    En revanche, je ne pense pas que ce soit persistant…

    • [^] # Re: ça existait déjà

      Posté par . Évalué à 7.

      La commande pushd est effectivement interessante, mais n'a pas du tout la même utilité. pushd fait une pile de dossier de travail, alors que ccd me permet d'attendre tout les signets en même temps. De plus, les signets sont communs entre tout les terminaux ouvert (mais sont différents pour chaque utilisateurs).

      bépo powered

    • [^] # Re: ça existait déjà

      Posté par (page perso) . Évalué à 1.

      Aaaaaaahhhhhhhhh je savais même pas que ca existait ! C'est vraiment top, ca va grandement me faciliter la vie ! Merci !

      Opera le fait depuis 10 ans.

      • [^] # Re: ça existait déjà

        Posté par (page perso) . Évalué à 2.

        Bien plus basique, mais très pratique aussi, il y a "cd -", qui revient dans le répertoire où tu étais avant le dernier cd.

        • [^] # Re: ça existait déjà

          Posté par (page perso) . Évalué à 1.

          Je connaissais déjà, mais souvent le dossier qui m'intéresse n'est pas le dernier dans lequel j'ai été.

          Opera le fait depuis 10 ans.

          • [^] # Re: ça existait déjà

            Posté par . Évalué à 5.

            Avec zsh et l'option AUTO_PUSHD, tu n'a plus se problème et cd gère l'ensemble des répertoires (et permet via cd - d'en voir la liste).

            Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

  • # C'est génial. Merci.

    Posté par . Évalué à 10.

    Bon comme tout est dit dans le titre, une blague que j'ai vu passer aujourd'hui :

    Comment faire disparaître le terrorisme ? Faire croire aux chinois que les jihadistes ont des vertus aphrodisiaques.

  • # cdargs....

    Posté par . Évalué à 2.

    cdarg fait la même chose (avec la completion) - et il y a même un mode pour emacs…

    http://www.skamphausen.de/cgi-bin/ska/CDargs

    • [^] # Re: cdargs....

      Posté par . Évalué à 1.

      Je viens de l'installer. C'est assez sympa. Avec bash, la complétion fonctionne à merveille, mais avec zsh c'est pas du tout le cas. D'ailleurs avec zsh quand je source le fichier /usr/share/cdargs/cdargs-bash.sh, il me dit que la commande complete n'existe pas. Une idée ?

      bépo powered

      • [^] # Re: cdargs....

        Posté par (page perso) . Évalué à 2.

        Combo : cdargs-bash.sh. Ce nom semble fortement indiquer qu'il utilise des fonctions spécifiques à bash ;-)

        ⚓ À g'Auch TOUTE! http://afdgauch.online.fr

  • # Edit

    Posté par . Évalué à 2.

    Je viens de m'apercevoir que j'ai fait une faute de copier-coller en voulant renommer de manière plus claire le dossier de stockage. Dans la fonction ccd, le dossier ~/.ccd est en fait ~/.signet (dans le if et le cd). Je suis désolé.

    Si un modo pouvais modifier ça.

    bépo powered

  • # Autojump

    Posté par . Évalué à 10.

    Autojump est disponible dans toute bonne distribution et permet de "sauter" d'un dossier à l'autre avec quelques lettres.

    Bon il n'y a pas la possibilité d'associer un alias à un chemin mais ça peut faire l'objet d'une requête de fonctionnalité.

    • [^] # Re: Autojump

      Posté par . Évalué à 2.

      Et fasd est plus puissant car il permet de sauter de répertoires, mais également de trouver des fichiers et de lancer d'autres actions (mplayer, vim, ou ce qu'on veut).
      https://github.com/clvv/fasd

      Il est inspiré de autojump, j et v.

  • # bonne idée mais...

    Posté par . Évalué à 4.

    NB : ccd sans arguments permet toujours d'aller dans le dernier dossier enregistré (avec ou sans signet nommé).

    encore faut-il avoir fait l'enregistrement du dossier.

    sinon en bash il y a cd - qui renvoie dans le dernier dossier utilisé
    cd - permet de revenir au dossier precedent

    cd - ; cd - te faisant evidemment revenir dans le dossier en cours

    • [^] # Re: bonne idée mais...

      Posté par (page perso) . Évalué à 8. Dernière modification le 09/01/15 à 23:36.

      et avec zsh, cd -2 te fait retourner encore un cran plus loin dans l'historique, et cd -<TAB> autocomplete depuis l'historique des répertoires précédents.

      • [^] # Re: bonne idée mais...

        Posté par . Évalué à 1.

        Chez moi ça ne marche pas :

        $ cd -2
        cd: no such entry in dir stack
        

        et cd -<TAB> ne me donne rien. Pourtant cd - marche très bien, je l'utilise tout les jours. Tu as fait quelque chose, (tel qu'activer un plugin de oh-my-zsh) ?

        bépo powered

        • [^] # Re: bonne idée mais...

          Posté par . Évalué à 5.

          Je crois que c'est en activant l'option auto_pushd. Ce qui permet avec cd de retrouver tout le comportement de pushd/popd.

          Tu peux aussi utiliser des alias de répertoires avec hash -d zsh="/usr/src/zsh". Ce qui a l'avantage de fonctionner partout (avec cp par exemple).

          Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

          • [^] # Re: bonne idée mais...

            Posté par . Évalué à 4.

            Et j'allais oublier, tu as l'option AUTO_CD (dispo aussi sous bash), qui te permet de ne même pas avoir à taper "cd ".

            Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

    • [^] # Re: bonne idée mais...

      Posté par . Évalué à 2.

      encore faut-il avoir fait l'enregistrement du dossier.

      Je ne voit pas trop en quoi c'est un problème. C'est la même chose avec les buffer dans vim, tant que tu ne les as jamais utilisé ils sont encore vide. Comme ta remarque m'a titillé l'esprit j'ai voulu vérifier. Dans le cas où on n'a jamais utilisé x, alors on obtient bien l'erreur suivante :

      $ccd
      Le signet  n'existe pas
      

      avec certes un espace de trop :)

      Pour la commande cd -, je connaissais, mais l'utilité n'est pas tout à fait la même. cd - est parfais sur une période courte (une heure max), mais au delà les signets sont plus adapté à mon sens. Par contre c'est une bonne idée d'en parler pour ceux qui ne connaissaient pas.

      bépo powered

  • # Mes trucs à moi.

    Posté par (page perso) . Évalué à 1.

    Jusqu'à présent j'utilise ça :

    jump ()
    {
        cd -P "$MARKPATH/$@" 2> /dev/null || echo "No such mark: $1"
    }
    mark ()
    {
        mkdir -v -p "$MARKPATH";
        ln -s "$(pwd)" "$MARKPATH/$1"
    }
    marks ()
    {
        ls -CF --color=auto -l "$MARKPATH" | sed 's/  / /g' | cut -d' ' -f9- | sed 's/ -/\t-/g' && echo
    }

    Je te remercie, tu simplifie la solution.

    « Il vaut mieux mobiliser son intelligence sur des conneries que mobiliser sa connerie sur des choses intelligentes. »

    • [^] # Re: Mes trucs à moi.

      Posté par . Évalué à 1.

      Ta commande marks est effectivement un peu trop complexe et pas très robuste. Chez moi cela marche pas. Je pense que le 1er sed devrait être 's/ */ /g'

      Quelque chose comme cela serait probablement plus élégant (en bash):

      for i in $MARKPATH/* ; do    
        printf "%-10s -> %s\n" "$(basename "$i")" "$(readlink "$i")"; 
      done | sort
      
  • # Dynamic named directories avec zsh

    Posté par (page perso) . Évalué à 3.

    zsh a une fonctionnalité de nom dynamique pour les répertoires. Ce sont des répertoires de la forme ~[X]. zsh appelle une fonction pour faire la traduction dans un sens ou dans l'autre (ce qui est utile pour que ton prompt affiche ~[titi]/toto $).

    Je l'utilise pour faire des bookmarks ici.

    bookmark titi
    cd /
    emacs ~[titi]/toto.txt
    

    L'avantage, c'est que zsh gère pas mal de choses, dont la complétion et que cela fonctionne avec toutes les commandes. Comme taper ~[, c'est pas facile, je tape @@ à la place et zle le transforme en ~[ et ensuite, j'utilise la complétion.

  • # déplacement rapide entre build et sources

    Posté par . Évalué à 1.

    Si vous êtes programmeur, vous connaissez certainement l'astuce consistant à séparer le dossier de 'build' du dossier contenant les sources. Cela évite de polluer celui ci avec tout un tas de fichiers inutiles pour SVN, GIT, …

    Les systèmes de build permettant cela vont en général créer un clone de la hiérarchie de dossiers sources. Se pose alors le problème de passer rapidement d'un dossier à un autre ; par exemple de …/src/xxx/yyy/zzz/ à …/build/xxx/yyy/zzz et inversement.

    Au boulot, j'ai une macro '@' pour cela (si! si! c'est legal en bash).
    Je suis entre 2 jobs donc mon bashrc est archivé. Je peux le retrouver ci cela intéresse quelqu'un (mais la macro n'est pas non plus très difficile à coder)

    L'idée est qu'il suffit de créer une paire de liens symboliques pour associer les
    racines des deux dossiers src et build
    …/src/.at -> …/build
    …/build/.at -> …/src

    La macro @ explore récursivement le dossier actuel et ses parents à la recherche d'un lien .at et saute alors au sous dossier correspondant.

    Par exemple, @ depuis …/src/xxx/yyy/zzz/
    - pas de …/src/xxx/yyy/zzz/.at
    - pas de …/src/xxx/yyy/.at
    - pas de …/src/xxx/.at
    - trouve …/src/.at -> …/build/
    donc 'cd ../build/xxx/yyy/zzzz'

    Et cela marche évidemment dans les 2 sens et c'est vraiment très pratique.

    • [^] # Re: déplacement rapide entre build et sources

      Posté par . Évalué à 1.

      Pour ceux intéressés

      #
      # Toggle between directory structures with similar hierarchies.
      #
      # The root of each directory structure must contain a symbolic link '.at' 
      # pointing to the root of the other directory. 
      # 
      # IMPORTANT: Both symbolic links must be absolute (/udd/bob/foo but not ../foo)
      #
      # Example: 
      #
      #  Consider two directories /udd/bob/work and /udd/scratch/work with identical 
      #  structured (as created by a typical 'configure' script) 
      # 
      #  cd /udd/bob/work ; ln -s /udd/scratch/work .at
      #  cd /udd/scratch/work ; ln -s /udd/bob/work .at
      #
      # Then you can do things like that:
      #
      #  cd /udd/bob/work/src/lib 
      #  edit myfile.c
      #  @                            -> equivalent to 'cd /udd/scratch/work/src/lib'
      #  make                           
      #  @                            -> equivalent to 'cd in /udd/bob/work/src/lib' 
      #  edit myfile.c 
      #
      #
      function @ () {
        local DIR HERE DEST
        DIR=$PWD
        HERE="$PWD/"
        DEST=
        while [[ "$DIR" != "/" ]] ; do 
          if [ -L $DIR/.at -a -d $DIR/.at ] ; then 
            DIR2=$(readlink -n $DIR/.at)
            cd ${HERE/#$DIR/$DIR2}
            return 
          fi
          DIR=$(dirname $DIR) ;
        done
        echo "*** unmanaged directory (symlink '.at' not found) ***"
      }
      
      • [^] # Re: déplacement rapide entre build et sources

        Posté par . Évalué à 1.

        Je m'aperçois que ma macro n'est pas résistante aux espaces dans les noms de dossier. Honte sur moi!

         function @ () {
          local DIR HERE DEST
          DIR="$PWD"
          HERE="$PWD/"
          DEST=
          while [[ "$DIR" != "/" ]] ; do 
            if [ -L "$DIR/.at" -a -d "$DIR/.at" ] ; then 
              DIR2="$(readlink -n "$DIR/.at")"
              cd "${HERE/#$DIR/$DIR2}"
              return 
            fi
            DIR="$(dirname "$DIR")" ;
          done
          echo "*** unmanaged directory (symlink '.at' not found) ***"
        }
        
  • # CDPATH

    Posté par . Évalué à 5.

    Je suis surpris que personne n'ai mentionné CDPATH.
    Il s'agit d'une variable d'environnement similaire à PATH, mais qui indique à 'cd' où chercher le dossier destination.

  • # Bonne astuce

    Posté par . Évalué à 2.

    Merci c'est une astuce que je vais adopter !

    Sinon :

    • Ne pas oublier de mkdir ~/.signet avant

    • On peut utiliser source ~/.truc-chose-shell-rc pour en profiter sans se relogguer

    • Cette phrase semble souffrir d'un problème de copié-collé

    Si j'ajoute une argument, par exemple x signet1 alors ccd signet1 me permettra de crée un signet nommé ?,

    • [^] # Re: Bonne astuce

      Posté par . Évalué à 1.

      C'était peut être pas clair, mais ce que je voulais dire c'est que x signet1 créer une signet qui n'est pas anonyme.

      bépo powered

      • [^] # Re: Bonne astuce

        Posté par . Évalué à 2.

        Oui du coup

        Si j'ajoute une argument, par exemple x signet1 alors ccd signet1 cela me permettra de crée un signet nommé,

        • [^] # Re: Bonne astuce

          Posté par . Évalué à 1.

          Ralala, tu as raison. J'avais pourtant relu la phrase que tu citais, mais je ne m'en suis pas rendu compte ! Autant pour moi.

          bépo powered

  • # Completion bash pour ccd

    Posté par . Évalué à 3.

    Voici une version possible de la completion BASH pour la commande ccd de l'article ci-dessus.

    function _ccd() {
        local cur
        cur="${COMP_WORDS[COMP_CWORD]}"    
        COMPREPLY=( $HOME/.signet/save${cur}* )
        COMPREPLY=( ${COMPREPLY[@]#$HOME/.signet/save} ) 
        return 0
    }
    
    complete -F _ccd ccd
    
    • [^] # Re: Completion bash pour ccd

      Posté par . Évalué à 2.

      J'ai remarqué un bug en cas de completion non-existante( xxx est complété en xxx* ). La version suivante résout ce problème

      function _ccd() {
          local cur prev opts
          cur="${COMP_WORDS[COMP_CWORD]}"    
          COMPREPLY=( $(shopt -s nullglob; echo $HOME/.signet/save${cur}* ) )
          COMPREPLY=( ${COMPREPLY[@]#$HOME/.signet/save} ) 
          return 0
      }
      
      complete -F _ccd ccd
      
  • # ranger file browser

    Posté par . Évalué à 2.

    Sinon, dans la catégorie un peu au-dessus car on parle d'un navigateur de fichiers, il y a ranger: https://github.com/hut/ranger

    Navigateur de fichiers à la vim. Dedans, on peut avoir des onglets, spécifier des marques pages, y sauter rapidement, ouvrir un shell dans tel répertoire ou manipuler les fichiers.

    Il est juste merveilleux ! (je l'utilise plus que Dired d'Emacs maintenant, c'est dire !)

  • # Encore mieux ?

    Posté par . Évalué à 1.

    Moi ce que j'aimerais c'est plutôt quelque chose dans le même genre que ctrlp :
    https://github.com/kien/ctrlp.vim

    • [^] # Re: Encore mieux ?

      Posté par . Évalué à 1.

      Et fzf a l'air d'être fait pour ça: https://github.com/junegunn/fzf
      mais je n'ai pas encore essayé. D'après sa doc: «Fuzzy completion for files and directories can be triggered if the word before the cursor ends with the trigger sequence which is by default **» (sous bash seulement, zsh est en TODO :( )

  • # j'utilise CDPATH

    Posté par . Évalué à 3.

    qui est une variable d'environnement contenant plusieurs répertoires ;)

    typiquement j'ai un truc du genre CDPATH=.:$HOME:/local/sources

    l'avantage c'est que ça marche déjà avec la completion auto de bash :)

    Il ne faut pas décorner les boeufs avant d'avoir semé le vent

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n'en sommes pas responsables.