Pourquoi le caractère générique * ne fonctionne-t-il pas lors du changement de directory?

Par exemple, je suis dans mon directory:

/home/myname 

et puis je veux un CD dans un autre directory.

 /home/pulsar/... 

Puisque je dois aller assez loin dans l'autre directory, comment puis-je y arriver sans avoir à taper toute la ligne? j'ai essayé

 cd */thedirectoryiwanttogointo 

mais cela ne fonctionne pas. Je dois taper toute la ligne.

Probablement votre joker ne fonctionne pas parce que:

  • il n'y avait pas de correspondance pour le caractère générique de l'location que vous avez donné, ou
  • il y avait plus d'un match.

L'approche habituelle (dans un shell) pour se déplacer fréquemment entre les sous-directorys consiste à utiliser la fonction CDPATH , ainsi que pushd et popd .

La fonction CDPATH (peut-être d'abord vu dans tcsh) est une list de directorys séparés par deux-points. Si le parent de votre nom de domaine est raisonnablement unique, vous pouvez append le parent à la list.

Pour plus de lecture (la page de manuel de votre shell doit être la première):

  • Qu'est-ce que le CDPATH?
  • 3.4. Modification des directorys avec cd (Guide étape par étape Red Hat Enterprise Linux)
  • Comment changer le CDPATH pour les shells C: csh et tcsh

pushd et popd sont plus récents que le CDPATH , mais datent toujours du milieu des années 1990. Ils vous permettent de sauvegarder votre directory actuel ("pushing" sur une stack) et de le restaurer ("popping" à partir d'une stack) au cours de leurs commands cd respectives. Pour plus d'informations:

  • Comment utiliser les commands pushd et popd?
  • Utiliser pushd et popd sous Linux

D'autres personnes utilisent des alias de shell ou des liens symboliques. Ceux-ci sont plus utiles lorsque vous allez à des endroits bien connus.

Vous voulez que l'extension de caractères generics trouve un path n'importe où sur le système. Vous pouvez le faire si vous spécifiez correctement le motif:

 cd /**/thedirectoryiwanttogointo 

va travailler dans zsh et pêcher par défaut, dans Bash si vous avez d'abord shopt -s globstar , dans tcsh si vous set globstar , dans ksh93 si vous set -o globstar , dans yash si vous set -o extended-glob .

Cela fonctionne car le caractère générique est utilisé dans un path absolu commençant par / au lieu d'être relatif au directory courant et lorsque vous optez pour l'utilisation du model ** , il s'étend à un nombre quelconque de sous-directorys.

Bien que cela fonctionne, il est susceptible de prendre très longtime . Votre shell doit searchr dans votre système tout le file correspondant. Vous pouvez réduire cela en fournissant un préfixe plus long pour rogner davantage de l'espace de search:

 cd /home/pulsar/**/thedirectoryiwanttogointo/ 

Plus vous avancez, less il y aura de searchs à faire. Si l'arborescence de directorys est assez clairsemée, cela ne prendra pas trop de time et est réellement pratique à utiliser. Le suivi / assure que l'expansion est seulement à un directory, ce qui supprime une variété d'ambiguïté qui pourrait se produire.

S'il y a plus d'une correspondance, le résultat dépendra de votre shell. Bash et le poisson passera à la première correspondance alphabétique, ignorant l'ambiguïté. tcsh et yash signaleront une erreur. zsh et ksh l'interpréteront comme une tentative d'utiliser l'une de leurs fonctionnalités avancées de commutation de directory et signaleront probablement une erreur.


Si vous utilisez probablement le même directory à plusieurs resockets, il est préférable d' CDPATH le parent dans CDPATH ou de créer une variable shell $FOO vous pouvez utiliser à la place du path long. Vous pouvez combiner la variable shell avec ** expansion pour save plus de frappe si vous l'utilisez souvent.

Si vous allez toujours dans le même directory profond, une solution simple consiste simplement à créer un lien symbolique:

 ln -s ~/foo/bar/baz/quux/etc/etc/etc/target ~/shortcut 

Si vous êtes déjà allé dans le directory, une autre solution consiste à searchr dans l'historique de vos commands le nom que vous souhaitez; appuyez sur ctrl-R et les caractères à searchr. Ceci est bash-spécifique, mais j'imagine que la plupart des coquilles modernes ont une facilité similaire.

En supposant que tous les directorys cibles possibles se trouvent sous /home et qu'il n'y a pas de caractères de nouvelle ligne dans les noms de directory, vous pouvez utiliser cette fonction shell:

 cds() { cd "$(find /home -type d -name "$1" | head -n 1)" } $ cds thedirectoryiwanttogointo 

Bien sûr, en fonction du nombre de sous-directorys et de files sous /home et de la possibilité pour votre operating system de mettre en memory cache tout l'tree en memory, les performances varient considérablement.

Sur les systèmes GNU, vous pouvez accélérer et rendre plus fiables les caractères newline dans les noms de files en utilisant cette syntaxe à la place:

 cds() { cd "$(find /home -type d -name "$1" -print -quit)" } 

Cela arrêtera la search dès que la première correspondance sera trouvée.

Notez que l'argument est pris comme un model, donc vous pouvez faire:

 cds 'foo*bar' 

par exemple cd dans le premier directory (l'ordre n'est pas spécifié) dont le nom commence par foo et se termine par une bar .