Comment puis-je cd dans un répertoire sans écrire son nom?

8

Parfois, c'est ennuyeux d'accéder à un répertoire avec le nom du dossier. Disons que j'ai un répertoire nommé a b c d. Outre l'utilisation Tab, existe-t-il un moyen d'accéder au dossier sans taper le nom du répertoire?

Je sais que Linux a un identifiant unique pour chaque fichier particulier. Puis-je l'utiliser pour accéder au dossier? Je ne sais pas si cela peut être fait ou comment le faire.

Je pense que lorsque Linux implémente un système de fichiers, il compare l'unicité de deux noms de répertoire. Ainsi, chaque répertoire doit être unique dans un espace. Mais je pense que c'est comme une clé primaire dans un système de base de données. La clé primaire est-elle le nom du répertoire ou existe-t-il un autre identifiant unique (peut-être certains numéros stockés «sous le capot»)?

Essayez de penser à cela comme un processus. Si vous exécutez la commande pssur un terminal, il génère une liste de processus avec le nom et le numéro de chaque processus. Vous devez appeler ce processus avec le numéro de processus. De même, existe-t-il un numéro pour un répertoire afin que vous puissiez appeler le répertoire avec son numéro au lieu de l'appeler avec son nom?


Après une enquête plus approfondie, j'ai constaté que chaque répertoire a un unique inode. Cependant, je n'ai jusqu'à présent trouvé aucune commande intégrée pour accéder à un répertoire par son inode.

Maruf
la source
1
les caractères génériques fonctionnent aussi. sinon installez zshau lieu debash
Rinzwind
Ok, les caractères génériques ne sont pas la réponse que je recherche. besoin de penser à zsh
Maruf
Vous devez accéder à un répertoire comme celui-ci ou il y en a plusieurs?
Sergiy Kolodyazhnyy
Ajoutez votre solution (qui pourrait être intéressante en passant) comme réponse au lieu de l'ajouter à votre question. Voilà pourquoi les réponses sont faites!
kos
Faites que ce programme imprime simplement le chemin et faites un cd $(icd XXXX)--- vous venez de réécrire cette findpartie. Maintenant, votre prochaine tâche est ... vérifiez ce qui est plus efficace, votre programme ou find:-P.
Rmano

Réponses:

2

Solution faite par OP

Aucune commande intégrée trouvée ici. Mais finalement je suis capable d'écrire un programme C pour utiliser cd (permet d'appeler mon programme icd == (cd inode)) pour entrer dans un dossier en utilisant la valeur inode. Ici, je poste le code brut.

Mais il y a un problème fondamental auquel j'ai été confronté ici. Lors du codage de l'exécution, un code C à partir d'un bash était nécessaire pour créer un processus enfant sous le processus bash (processus parent). À partir du processus enfant, l'espace répertoire est nouveau et je ne peux pas accéder à l'espace répertoire du processus parent à partir de là. Donc, rien ne pouvait être fait à part invoquer une nouvelle fenêtre bash d'ici. À l'avenir, j'essaierai de mettre en œuvre une nouvelle fonctionnalité d'onglet si les gens sont intéressés par cela. Mais je crois que j'ai fait face à beaucoup de critiques pour avoir fait cela. Les gens pourraient donc ne pas être intéressés. Je viens de faire pour mon amusement.

Le code RAW est partagé ici,

#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>
#include<dirent.h>
#include <unistd.h>
#include <grp.h>
#include<pwd.h>

using namespace std ;

int main(int argc , char *argv[] ) {

  struct stat ITR ;

  if( argc != 2 ) {
    printf("\nWrong Command\n\n") ;
    return 1 ;
  }

  long long given_inode = 0 ;
  for( int i =0 ; argv[1][i] ; i++ ){
    given_inode *= 10 ;
    given_inode += (argv[1][i]-'0') ;
  }

//  if (stat(argv[1], &ITR) == -1) {
//    perror("stat");
//    return 1  ;
//  }

  printf("%s\n",argv[0]) ;
    char PWD[1000] ; 
    getcwd( PWD , 1000 ) ;

  DIR *d;
  struct dirent *p;
  char path[100000] ;
  d = opendir(".");
  if( d != NULL ) {
    while( (p = readdir(d))!= NULL ) {
        strcpy( path , "./" ) ;
        strcat( path, p->d_name ) ;
        stat(path, &ITR) ;
        //printf("%s --> ",path) ;
        //printf("%ld\n",ITR.st_ino) ;
        if( ITR.st_ino == given_inode ) {
          strcpy( path , "gnome-terminal --working-directory=" ) ;
          strcat( path, PWD ) ;
                    strcat( path, "/" ) ;
                    strcat( path, p->d_name ) ;
                    system(path) ; 
                    //printf("%s\n",path) ;
                    return 0 ;
        }
    }
  }
  printf("icd %lld:No such file or directory\n",given_inode) ;
  return 0 ;

}

J'utilise le terminal gnome ici. Évidemment, pour les autres distributions, le code sera modifié.

Pilot6
la source
1
Si vous pouviez vous déplacer vers un répertoire dans un script shell, vous pouvez source le script pour accomplir ce que vous voulez. Définissez un alias pour raccourcir la commande.
daltonfury42
19

Toute entité dans (la plupart) des systèmes de fichiers sous Linux a un identifiant unique appelé an inode. Notez qu'un fichier peut avoir plus d'un nom ( lien dur ), mais les répertoires n'ont qu'un seul lien dans tous les systèmes de fichiers que je connais. Notez que le concept d'inode est local au système de fichiers, de sorte que dans deux périphériques différents (partition ou autre) l'unicité n'est pas garantie.

Vous pouvez voir l'inode de votre répertoire avec ls -ldi:

[:~] % ls -ldi tmp/uffa                     
20873234 drwxrwxr-x 2 romano romano 4096 Jun 26  2014 tmp/uffa

Vous savez donc que votre répertoire contient l'inode 20873234. Vous pouvez maintenant y basculer avec la commande:

[:~] % cd "$(find ~ -inum 20873234 2> /dev/null)"  
[:~/tmp/uffa] %

(Notez que le 2> /dev/nullest de fermer les messages d'erreur sur les répertoires illisibles le long du chemin d'accès.)

Cette commande analysera l'intégralité de votre répertoire personnel, alors soyez patient. 1

Mais qu'en est-il de l'utilisation cdet de l'achèvement TAB de votre shell?


1. Ce doit être le plus 2 chose inefficacej'ai jamais misligne ... une ode àentropie. La raison en est que la «clé primaire» sous laquelle l'accès à un fichier ou à un répertoire est optimisé, rapide et direct est - devinez quoi? - le chemin:/dir/dir/file_or_dir. De plus, pour vous accorder l'accès à un répertoire donné, le système doit vérifier toutes les autorisations dans le chemin ... encore une fois, accéder par inode signifie scanner récursivement le système de fichiers.

2. Eh bien, vous pouvez aggraver les choses en scannant à partir de/. 3

3. Mais cela ne fonctionnera pas, car les inodes ne sont uniques que par système de fichiers (par montage).

Rmano
la source
Merci @Romano. En fait, je pensais au problème. Je ne sais pas si le problème se transformerait en une solution aussi inefficace. Mais réfléchissez à la solution. Vous pouvez facilement écrire un programme ac et le mettre dans / bin, puis essayer de l'exécuter avec le seul numéro d'inode. Je publierai le code si je suis capable d'écrire une telle réflexion.
Marouf
1
et aussi on pense que je dois savoir. Je comprends la première partie de cette commande. "$ (trouver ~ -inum 20873234 ******)". mais je ne sais pas pourquoi vous écrivez ceci, "2> / dev / null". Pouvez-vous clarifier encore une fois.
Marouf
4
@Maruf, cela ne fonctionnera pas, en termes d'efficacité. La « clé primaire » en vertu de laquelle l'accès à un fichier ou un répertoire est optimisé, rapide et directe est, devinez quoi, le chemin ... /dir/dir/file_or_dir. Votre programme C devra également analyser le système de fichiers, et finda été optimisé au cours des 40 dernières années ... toujours --- pourquoi? Si vous avez besoin d'un raccourci, utilisez a="/my/really/strange and long/dir path name/"et puis cd "$a". Je ne peux pas le battre. Ou utilisez des liens symboliques.
Rmano
1
Un bon +1. J'étais sur le point d'écrire quelque chose de similaire, mais j'étais trop paresseux, car la tâche n'avait aucun sens. @Rmano
Pilot6
3
@Rmano J'ajouterais qu'en général, même sur un seul système de fichiers, il peut y avoir plusieurs fichiers qui ont le même inode, c'est-à-dire des liens physiques. Puisque nous parlons de répertoires ici, il se trouve que chaque répertoire a un inode unique (les répertoires ne peuvent pas être liés par un lien dur.) De plus, je pense que la raison pour laquelle on ne peut pas accéder directement à un fichier via son inode est que cela contournerait n'importe quel répertoire traversée, nécessaire pour déterminer si un utilisateur est autorisé à accéder à la ressource correspondante. (Donc, si un répertoire était accessible par son inode, le noyau devrait de toute façon déterminer son chemin d'accès.)
Malte Skoruppa
8

Vous pouvez faire Tabpivoter les dossiers disponibles au lieu de les répertorier. Modifiez le fichier ~/.inputrcet ajoutez

"\C-i": menu-complete
"\e[Z": "\e-1\C-i"

Si vous le souhaitez pour tous les utilisateurs, modifiez-le à la /etc/inputrcplace.

Appuyez sur Ctrl+ xet Ctrl+ rpour le rendre efficace.

Maintenant, utilisez cdTabpour naviguer vers votre dossier sans écrire son nom. cdShift+ Tabtournera dans l'autre sens.

N'oubliez pas que cd -cela vous amènera au dernier dossier visité.

Katu
la source
C'est une bonne réponse. Pouvez-vous le faire afficher une fois, puis le faire pivoter?
daltonfury42
1
Vous pouvez l'assigner à un autre raccourci. J'utilise Eclipse et j'ai l'habitude de Ctrl + espace pour la saisie automatique, donc j'utilise "\ C-": menu-complete à la place, en laissant l'onglet tel quel.
Katu
5

Vous pouvez utiliser des caractères génériques shell.

Par exemple, je peux faire

cd a?b?c?d

ou

cd a\*b\*c\*d

Et il étendra les caractères génériques au nom réel et modifiera ce répertoire. En supposant que c'est le seul répertoire qui corresponde.

Si vous avez les deux a b c det a1b2c3d, puis cd a?b?c?ds'étendra à l'un cd a1b2c3d a b c dou l' autre cd a b c d a1b2c3d(l'ordre réel dépendra du noyau, du système de fichiers ...), et bash vous déplacera silencieusement vers le premier chemin.

D'un autre côté, vous n'avez souvent pas de dossiers nommés de manière similaire, donc quelque chose comme a*dest suffisant pour développer cela sans avoir à taper tous les caractères intermédiaires. Ceci est particulièrement utile lorsque vous n'êtes pas en mesure de le taper (par exemple, les noms sont dans un script différent, ou même un codage différent), et que vous auriez sinon dû coder en octal le nom de fichier.

Ange
la source
3

Vous pouvez trouver ce répertoire dans un gestionnaire de fichiers, par exemple nautilus et il suffit de le faire glisser vers le terminal.

Si vous avez déjà tapé cdterminal, vous obtiendrez la commande.

Pilot6
la source
En fait, j'essaie de tout faire depuis le terminal. :). Donc pas besoin de penser au nautile. Je pense qu'il doit y avoir une procédure pour accéder au dossier. Comme Linux, enregistrez toujours un identifiant unique pour un fichier particulier. Mais je ne sais pas comment faire cela ou cela peut-il être fait.
Marouf
Ce que vous demandez n'est pas clair. Il n'est pas possible de passer à un répertoire ne saisissant pas son nom d'une manière ou d'une autre.
Pilot6
Voir la déclaration. Je l'ai mis à jour.
Marouf
Ou si c'est le problème avec un seul fichier, vous pouvez ajouter un alias.
daltonfury42
1

Je ne sais pas si c'est exactement ce que vous demandez, mais vous avez zshquelques astuces pour accéder à un répertoire par d'autres moyens que de taper le nom strict du répertoire; d'une part, vous pouvez taper une partie du nom et il se développera jusqu'au nom complet du répertoire, ce qui permet des choses très utiles, par exemple:

entrez la description de l'image ici

Frapper TAB...

entrez la description de l'image ici

kos
la source
1

Le moyen le plus simple consiste à double-cliquer sur le nom du répertoire (en supposant qu'il soit visible à l'écran), puis à taper cd suivi d'un espace et à cliquer sur le bouton de la molette de votre souris et il copiera et collera le nom du répertoire que vous avez mis en surbrillance. Appuyez sur la touche Entrée pour passer au répertoire requis.

J'utilise cette procédure tout le temps et elle ne se limite pas aux noms de répertoire. Il peut être utilisé pour toutes les commandes utilisant la ligne de commande.

Bonne chance.

Allen
la source
Cela n'échappera pas aux caractères spéciaux
Scz
1

S'il ne s'agit que d'un ou de quelques répertoires, pourquoi ne pas avoir d'alias dans votre bashrc ou dans les fichiers init? Par exemple:

alias abc='cd /tmp/"a b c"'

Ensuite, chaque fois que vous voulez y entrer, tapez simplement abc

Hopping Bunny
la source
0

Vous pouvez écrire un programme pour créer une table de hachage pour tous vos répertoires OS. Ce serait essentiellement un programme d'aplatissement des arbres.

Mais alors vous pourriez faire quelque chose comme hash-cd 32okjv02et cela ferait la recherche de table de hachage pour le 32okjv02mappage de répertoire to. et accédez à votre répertoire. Et ce serait vraiment rapide une fois tous vos répertoires indexés.

Vous devez alias mkdir pour appeler ce programme à chaque nouveau répertoire et peut-être écrire une commande de vérification / actualisation de table de hachage que vous pourriez exécuter chaque minute et à l'ouverture de session.

mutant_city
la source