Wie kann ich in ein Verzeichnis cd, ohne dessen Namen zu schreiben?

8

Manchmal ist es ärgerlich, auf ein Verzeichnis mit dem Ordnernamen zuzugreifen. Angenommen, ich habe ein Verzeichnis mit dem Namen a b c d. Gibt es neben der Verwendung Tabeine Möglichkeit, auf den Ordner zuzugreifen, ohne den Namen des Verzeichnisses einzugeben?

Ich weiß, dass Linux für jede einzelne Datei eine eindeutige Kennung hat. Kann ich damit auf den Ordner zugreifen? Ich weiß nicht, ob das tatsächlich geht oder wie es geht.

Ich denke, wenn Linux ein Dateisystem implementiert, vergleicht es die Eindeutigkeit zweier Verzeichnisnamen. Jedes Verzeichnis muss also in einem Leerzeichen eindeutig sein. Aber ich denke, dass es wie ein Primärschlüssel in einem Datenbanksystem ist. Ist der Primärschlüssel der Name des Verzeichnisses oder gibt es eine andere eindeutige Kennung (möglicherweise einige Nummern, die „unter der Haube“ gespeichert sind)?

Versuchen Sie, sich das wie einen Prozess vorzustellen. Wenn Sie den Befehl psauf einem Terminal ausführen , wird eine Prozessliste mit dem Namen und der Nummer jedes Prozesses ausgegeben. Sie müssen diesen Prozess mit der Prozessnummer aufrufen. Gibt es auch eine Nummer für ein Verzeichnis, damit Sie das Verzeichnis mit seiner Nummer anrufen können, anstatt es mit seinem Namen anzurufen?


Bei weiteren Untersuchungen habe ich festgestellt, dass jedes Verzeichnis ein eindeutiges Verzeichnis hat inode. Ich habe jedoch bisher keinen integrierten Befehl gefunden, um über dessen Verzeichnis auf ein Verzeichnis zuzugreifen inode.

Maruf
quelle
1
Platzhalter funktionieren auch. ansonsten zshstattbash
Rinzwind
Ok Wildcards ist nicht die Antwort, die ich suche. Ich muss über zsh nachdenken
Maruf
Sie müssen auf ein solches Verzeichnis zugreifen oder es gibt mehrere?
Sergiy Kolodyazhnyy
Fügen Sie Ihre Lösung (die übrigens interessant sein könnte) als Antwort hinzu, anstatt sie Ihrer Frage hinzuzufügen. Dafür sind Antworten gemacht!
Kos
Lassen Sie dieses Programm einfach den Pfad drucken und machen Sie einen cd $(icd XXXX)--- Sie haben diesen findTeil einfach neu geschrieben . Jetzt ist Ihre nächste Aufgabe ... überprüfen Sie, was effizienter ist, Ihr Programm oder find:-P.
Rmano

Antworten:

2

Lösung von OP

Hier wurde kein eingebauter Befehl gefunden. Aber schließlich kann ich ein C-Programm schreiben, um cd zu verwenden (nennen wir mein Programm icd == (inode cd)), um mit dem inode-Wert in einen Ordner zu gelangen. Hier poste ich den Rohcode.

Aber es gibt ein grundlegendes Problem, mit dem ich hier konfrontiert bin. Während der Codierungsausführung wird ein C-Code aus einer Bash benötigt, um einen untergeordneten Prozess unter dem Bash-Prozess (übergeordneter Prozess) zu erstellen. Vom untergeordneten Prozess aus ist der Verzeichnisbereich neu, und ich kann von dort aus nicht auf den Verzeichnisbereich des übergeordneten Prozesses zugreifen. Es konnte also nichts getan werden, außer von hier aus ein neues Bash-Fenster aufzurufen. In Zukunft werde ich versuchen, eine neue Tab-Funktion zu implementieren, wenn die Leute daran interessiert sind. Aber ich glaube, ich wurde dafür viel kritisiert. Die Leute könnten also nicht interessiert sein. Ich habe gerade für meine Unterhaltung getan.

RAW-Code wird hier geteilt,

#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 ;

}

Ich benutze hier Gnome Terminal. Für andere Distributionen wird der Code natürlich geändert.

Pilot6
quelle
1
Wenn Sie in ein Verzeichnis innerhalb eines Shell-Skripts wechseln können, können Sie das Skript als Quelle verwenden, um das zu erreichen, was Sie möchten. Definieren Sie einen Alias, um den Befehl zu verkürzen.
Daltonfury42
19

Jede Entität in (den meisten) Dateisystemen unter Linux hat eine eindeutige Kennung namens inode. Beachten Sie, dass eine Datei mehr als einen Namen ( Hardlink ) haben kann, Verzeichnisse jedoch nur einen Link in allen mir bekannten Dateisystemen haben. Beachten Sie, dass das Inode-Konzept lokal für das Dateisystem ist, sodass bei zwei verschiedenen Geräten (Partition oder was auch immer) die Eindeutigkeit nicht garantiert ist.

Sie können den Inode Ihres Verzeichnisses sehen mit ls -ldi:

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

Sie wissen also, dass Ihr Verzeichnis den Inode 20873234 hat. Jetzt können Sie mit dem folgenden Befehl dorthin wechseln:

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

(Beachten Sie, dass 2> /dev/nullFehlermeldungen zu nicht lesbaren Verzeichnissen entlang des Pfads geschlossen werden sollen.)

Dieser Befehl durchsucht das gesamte Home-Verzeichnis. Seien Sie also geduldig. 1

Aber was ist mit der Verwendung cdund der TAB-Vervollständigung Ihrer Shell?


1. Dies muss das sein 2 ineffizientwas ich je eine Ode geschrieben ... Entropie. Der Grund dafür ist, dass der „Primärschlüssel“, unter dem der Zugriff auf eine Datei oder ein Verzeichnis optimiert, schnell und direkt ist, - wissen Sie was? - der Pfadname :/dir/dir/file_or_dir. Um Ihnen Zugriff auf ein bestimmtes Verzeichnis zu gewähren, muss das System außerdem alle Berechtigungen im Pfad überprüfen. Auch hier bedeutet der Zugriff per Inode, dass das Dateisystem rekursiv gescannt wird.

2. Nun, Sie können die Sache noch schlimmer machen, indem Sie von scannen/. 3

3. Aber dann funktioniert es nicht, da Inodes nur auf Dateisystembasis (pro Mount) eindeutig sind.

Rmano
quelle
Danke @Romano. Eigentlich habe ich über das Problem nachgedacht. Ich weiß nicht, dass das Problem zu einer solchen ineffizienten Lösung werden würde. Aber denken Sie über die Lösung nach. Sie können einfach ein Wechselstromprogramm schreiben und es in / bin ablegen und dann versuchen, es mit der einzigen Inode-Nummer auszuführen. Ich werde den Code posten, wenn ich in der Lage bin, solche Gedanken zu schreiben.
Maruf
1
und man denkt auch, ich muss es wissen. Ich verstehe den ersten Teil dieses Befehls. "$ (find ~ -inum 20873234 ******)". aber ich weiß nicht, warum du das schreibst, "2> / dev / null". Kannst du das bitte noch einmal klären?
Maruf
4
@ Maruf, es wird nicht funktionieren, was die Effizienz betrifft. Der „Primärschlüssel“ , unter dem der Zugriff auf eine Datei oder ein Verzeichnis ist optimiert, schnell und direkt ist, erraten , was den Pfad ... /dir/dir/file_or_dir. Ihr C-Programm muss auch das Dateisystem scannen und findwurde in den letzten 40 Jahren optimiert ... immer noch --- warum? Wenn Sie eine Verknüpfung benötigen, verwenden Sie a="/my/really/strange and long/dir path name/"und dann cd "$a". Kann es nicht schlagen. Oder verwenden Sie Symlinks.
Rmano
1
Ein guter +1. Ich war kurz davor, etwas Ähnliches zu schreiben, aber ich war zu faul, da die Aufgabe überhaupt keinen Sinn hat. @Rmano
Pilot6
3
@Rmano Ich würde hinzufügen, dass es im Allgemeinen sogar auf einem einzelnen Dateisystem mehrere Dateien geben kann, die denselben Inode haben, dh Hardlinks. Da es sich hier um Verzeichnisse handelt, ist es wahr, dass jedes Verzeichnis einen eindeutigen Inode hat (Verzeichnisse können nicht fest verknüpft werden). Ich denke auch, dass man nicht direkt über seinen Inode auf eine Datei zugreifen kann, weil dies jedes Verzeichnis umgehen würde Durchquerung, die erforderlich ist, um festzustellen, ob ein Benutzer auf die entsprechende Ressource zugreifen darf. (Wenn also über sein Inode auf ein Verzeichnis zugegriffen werden könnte, müsste der Kernel seinen Pfad trotzdem bestimmen.)
Malte Skoruppa
8

Sie können Tabdie verfügbaren Ordner drehen, anstatt sie aufzulisten. Bearbeiten Sie die Datei ~/.inputrcund fügen Sie sie hinzu

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

Wenn Sie es für alle Benutzer möchten, bearbeiten Sie es /etc/inputrcstattdessen.

Drücken Sie Ctrl+ xund Ctrl+ r, um es wirksam zu machen.

Verwenden Sie nun cdTab, um zu Ihrem Ordner zu navigieren, ohne dessen Namen zu schreiben. cdShift+ Tabdreht sich in die andere Richtung.

Denken Sie daran, dass cd -Sie zum zuletzt besuchten Ordner gelangen.

Katu
quelle
Das ist eine gute Antwort. Können Sie es einmal anzeigen lassen und dann drehen?
Daltonfury42
1
Sie können dies einer anderen Verknüpfung zuweisen. Ich verwende Eclipse und bin es gewohnt, Strg + Leerzeichen für die automatische Vervollständigung zu verwenden, daher verwende ich stattdessen "\ C-": Menü-Vervollständigung und lasse die Registerkarte unverändert.
Katu
5

Sie können Shell-Platzhalter verwenden.

Zum Beispiel kann ich tun

cd a?b?c?d

oder

cd a\*b\*c\*d

Außerdem werden die Platzhalter auf den tatsächlichen Namen erweitert und in dieses Verzeichnis geändert. Angenommen, dies ist das einzige Verzeichnis, das übereinstimmt.

Wenn Sie beide a b c dund haben a1b2c3d, cd a?b?c?dwird auf entweder cd a1b2c3d a b c doder erweitert cd a b c d a1b2c3d(die tatsächliche Reihenfolge hängt vom Kernel, Dateisystem ... ab), und bash bringt Sie stillschweigend zum ersten Pfad.

Auf der anderen Seite haben Sie oft nicht so ähnlich benannte Ordner, so etwas a*dreicht aus, um dies zu erweitern, ohne alle Zwischenzeichen eingeben zu müssen. Dies ist besonders nützlich, wenn Sie es tatsächlich nicht eingeben können (z. B. wenn sich die Namen in einem anderen Skript oder sogar in einer anderen Codierung befinden) und Sie sonst den Dateinamen oktal codieren müssten.

Engel
quelle
3

Sie finden dieses Verzeichnis in einem Dateimanager, z. B. nautilus, und ziehen es einfach per Drag & Drop auf das Terminal.

Wenn Sie zuvor cdTerminal eingegeben haben, erhalten Sie den Befehl.

Pilot6
quelle
Eigentlich versuche ich alles vom Terminal aus zu machen. :). Sie müssen also nicht an Nautilus denken. Ich denke, es muss ein Verfahren geben, um auf die Datei zuzugreifen. Da Linux immer eine eindeutige Kennung für eine bestimmte Datei speichert. Aber ich weiß nicht, wie ich das machen soll oder kann das tatsächlich gemacht werden.
Maruf
Es ist unklar, was Sie fragen. Es ist nicht möglich, in ein Verzeichnis zu wechseln, in dem der Name nicht eingegeben wurde.
Pilot6
Siehe die Erklärung. Ich habe es aktualisiert.
Maruf
Wenn dies das Problem mit einer einzelnen Datei ist, können Sie einen Alias ​​hinzufügen.
Daltonfury42
1

Sie sind sich nicht sicher, ob Sie genau danach fragen, haben aber zsheinige nette Tricks, um auf andere Weise auf ein Verzeichnis zuzugreifen, als den strengen Namen des Verzeichnisses einzugeben. Zum einen können Sie einen Teil des Namens eingeben und dieser wird auf den vollständigen Namen des Verzeichnisses erweitert, was sehr nützliche Dinge ermöglicht, zum Beispiel:

Geben Sie hier die Bildbeschreibung ein

Schlagen TAB...

Geben Sie hier die Bildbeschreibung ein

kos
quelle
1

Am einfachsten ist es, auf den Verzeichnisnamen zu doppelklicken (vorausgesetzt, er wird auf dem Bildschirm angezeigt), dann cd gefolgt von Leerzeichen einzugeben und mit der Maus auf das Rad zu klicken. Der markierte Verzeichnisname wird dann kopiert und eingefügt. Durch Drücken der Eingabetaste wird dann in das gewünschte Verzeichnis gewechselt.

Ich benutze dieses Verfahren die ganze Zeit und es ist nicht nur auf Verzeichnisnamen beschränkt. Es kann für alle Befehle über die Befehlszeile verwendet werden.

Viel Glück.

Allen
quelle
Dies wird Sonderzeichen nicht entgehen
Scz
1

Wenn es sich nur um ein oder mehrere Verzeichnisse handelt, warum nicht Aliase in Ihrem bashrc oder in welchen Init-Dateien? Zum Beispiel:

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

Wenn Sie dann dort hineingehen möchten, geben Sie einfach ein abc

Hüpfender Hase
quelle
0

Sie können ein Programm schreiben, um eine Hash-Tabelle für alle Ihre Betriebssystemverzeichnisse zu erstellen. Es wäre im Grunde ein Baumabflachungsprogramm.

Aber dann könnten Sie so etwas tun hash-cd 32okjv02und es würde die Hash-Tabellensuche für die 32okjv02Zuordnung zum Verzeichnis durchführen. und springe zu deinem Verzeichnis. Und es wäre sehr schnell, wenn Sie alle Ihre Verzeichnisse indiziert hätten.

Sie müssten den Alias ​​mkdir verwenden, um dieses Programm in jedem neuen Verzeichnis aufzurufen und möglicherweise einen Befehl zum Überprüfen / Aktualisieren der Hash-Tabelle zu schreiben, den Sie jede Minute und bei der Anmeldung erstellen können.

mutant_city
quelle