¿Cómo puedo cd a un directorio sin escribir su nombre?

8

A veces es molesto acceder a un directorio con el nombre de la carpeta. Digamos que tengo un directorio llamado a b c d. Además de usar Tab, ¿hay alguna forma de acceder a la carpeta sin escribir el nombre del directorio?

Sé que Linux tiene un identificador único para cada archivo en particular. ¿Puedo usar esto para acceder a la carpeta? No sé si esto realmente se puede hacer o cómo hacerlo.

Creo que cuando Linux implementa un sistema de archivos, compara la unicidad de dos nombres de directorio. Por lo tanto, cada directorio debe ser único en un espacio. Pero creo que es como una clave primaria en un sistema de base de datos. ¿Es la clave principal el nombre del directorio o hay algún otro identificador único (quizás algunos números almacenados "bajo el capó")?

Intenta pensar en esto como un proceso. Si ejecuta el comando psen un terminal, genera una lista de procesos con el nombre y el número de cada proceso. Debe llamar a ese proceso con el número de proceso. Del mismo modo, ¿hay un número para un directorio para que pueda llamar al directorio con su número en lugar de llamarlo con su nombre?


En una investigación adicional, he encontrado que cada directorio tiene un único inode. Sin embargo, hasta ahora no he encontrado ningún comando incorporado para acceder a un directorio por su inode.

Maruf
fuente
1
los comodines también funcionan. de lo contrario, instálelo en zshlugar debash
Rinzwind
Ok comodines no es la respuesta que busco. Necesito pensar en zsh
Maruf
¿Necesita acceder a un directorio como ese o hay varios?
Sergiy Kolodyazhnyy
Agregue su solución (que puede ser interesante por cierto) como respuesta en lugar de agregarla a su pregunta. ¡Para eso están hechas las respuestas!
kos
Haga que el programa simplemente imprima la ruta y haga un cd $(icd XXXX)--- simplemente reescribió esa findparte. Ahora su próxima tarea es ... verifique qué es más eficiente, su programa o find:-P.
Rmano

Respuestas:

2

Solución hecha por OP

No se encontró ningún comando incorporado aquí. Pero finalmente puedo escribir un programa en C para usar cd (llamemos a mi programa icd == (inode cd)) para ingresar en una carpeta usando el valor de inode. Aquí estoy publicando el código en bruto.

Pero hay un problema fundamental que he enfrentado aquí. Mientras se codifica la ejecución, se necesita un código C de un bash para crear un proceso secundario en el proceso bash (proceso primario). Desde el proceso secundario, el espacio de directorio es nuevo, y no puedo acceder al espacio de directorio del proceso primario desde allí. Así que no se pudo hacer nada excepto invocar una nueva ventana de bash desde aquí. En el futuro, intentaré implementar una nueva función de pestaña si la gente está interesada en esto. Pero creo que he enfrentado muchas críticas por hacer esto. Entonces la gente podría no estar interesada. Acabo de hacer para mi diversión.

El código RAW se comparte aquí,

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

}

Estoy usando la terminal de GNOME aquí. Obviamente para otra distribución el código será cambiado.

Piloto6
fuente
1
Si pudiera moverse a un directorio dentro de un script de shell, puede obtener el script para lograr lo que desea. Definen un alias para acortar el comando.
daltonfury42
19

Cualquier entidad en (la mayoría) de los sistemas de archivos en Linux tiene un identificador único llamado an inode. Tenga en cuenta que un archivo puede tener más de un nombre ( enlace duro ), pero los directorios tienen solo un enlace en todos los sistemas de archivos que conozco. Tenga en cuenta que el concepto de inodo es local para el sistema de archivos, por lo que en dos dispositivos diferentes (partición o lo que sea) la unicidad no está garantizada.

Puede ver el inodo de su directorio con ls -ldi:

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

Entonces sabe que su directorio tiene el inodo 20873234. Ahora puede cambiar a él con el comando:

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

(Tenga en cuenta que 2> /dev/nulles para cerrar los mensajes de error sobre directorios ilegibles a lo largo de la ruta).

Este comando escaneará la totalidad de su directorio de inicio, así que sea paciente. 1

¿Pero qué pasa con el uso cdy la finalización TAB de su shell?


1. Esto debe ser lo másineficiente 2 que he publicado ... una oda a la entropía. La razón es que la "clave principal" bajo la cual el acceso a un archivo o directorio está optimizado, es rápido y directo es: ¿adivina qué? - el nombre de ruta:/dir/dir/file_or_dir. Además, para otorgarle acceso a un directorio dado, el sistema necesita verificar todos los permisos en la ruta ... así que nuevamente, acceder por inodo significa escanear recursivamente el sistema de archivos.

2. Bueno, puede empeorar las cosas escaneando desde/. 3

3. Pero entonces no funcionará, porque los inodes son únicos solo por sistema de archivos (por montaje).

Rmano
fuente
Gracias @Romano. En realidad estaba pensando en el problema. No sé si el problema se convertiría en una solución tan ineficiente. Pero piensa en la solución. Puede escribir fácilmente un programa de CA y ponerlo en / bin y luego intentar ejecutarlo con el único número de inodo. Publicaré el código si puedo escribir tal pensamiento.
Maruf
1
y también creo que necesito saberlo Entiendo la primera parte de este comando. "$ (find ~ -inum 20873234 ******)". pero no sé por qué estás escribiendo esto, "2> / dev / null". ¿Puedes aclarar una vez más?
Maruf
44
@ Maruf, no funcionará, en términos de eficiencia. La "clave principal" en virtud del cual se optimiza el acceso a un archivo o directorio, rápido y directo es, adivina qué, el nombre de ruta ... /dir/dir/file_or_dir. Su programa C también necesitará escanear el sistema de archivos, y findha sido optimizado durante los últimos 40 años ... aún así, ¿por qué? Si necesita un atajo, use a="/my/really/strange and long/dir path name/"y luego cd "$a". No puedo vencerlo. O usa enlaces simbólicos.
Rmano
1
Una buena +1. Estaba a punto de escribir algo similar, pero era demasiado vago, ya que la tarea no tiene ningún sentido. @Rmano
Pilot6
3
@Rmano Agregaría que, en general, incluso en un solo sistema de archivos, puede haber varios archivos que tengan el mismo inodo, es decir, enlaces duros. Como estamos hablando de directorios aquí, resulta cierto que cada directorio tiene un inodo único (los directorios no se pueden vincular). Además, creo que la razón por la que no se puede acceder directamente a un archivo a través de su inodo es que esto evitaría cualquier directorio transversal, necesaria para determinar si un usuario puede acceder al recurso correspondiente. (Entonces, si un inodo podía acceder a un directorio, el núcleo tendría que determinar su ruta de todos modos.)
Malte Skoruppa
8

Puede hacer Tabrotar las carpetas disponibles en lugar de enumerarlas. Edite el archivo ~/.inputrcy agregue

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

Si lo desea para todos los usuarios, edite en su /etc/inputrclugar.

Presione Ctrl+ xy Ctrl+ rpara hacerlo efectivo.

Ahora use cdTabpara navegar a su carpeta sin escribir su nombre. cdShift+ Tabrotará en la otra dirección.

Vale la pena recordar que cd -te llevará a la última carpeta visitada.

Katu
fuente
Esta es una buena respuesta. ¿Puedes hacer que se muestre una vez y luego girar?
daltonfury42
1
Puede asignar esto a otro acceso directo. Uso Eclipse y estoy acostumbrado a Ctrl + espacio para autocompletar, así que uso "\ C-": menu-complete en su lugar, dejando la pestaña como está.
Katu
5

Puede usar comodines de shell.

Por ejemplo, puedo hacer

cd a?b?c?d

o

cd a\*b\*c\*d

Y expandirá los comodines al nombre real y cambiará a ese directorio. Asumiendo que ese es el único directorio que coincide.

Si tiene ambos a b c dy a1b2c3d, cd a?b?c?dse expandirá a cualquiera cd a1b2c3d a b c do cd a b c d a1b2c3d(el orden real dependerá del núcleo, el sistema de archivos ...), y bash lo moverá silenciosamente a la primera ruta.

Por otro lado, a menudo no tiene carpetas con nombres similares, por lo que algo así a*des suficiente para expandir eso sin tener que escribir todos los caracteres intermedios. Esto es especialmente útil cuando en realidad no puede escribirlo (por ejemplo, los nombres están en una secuencia de comandos diferente, o incluso una codificación diferente), y de lo contrario habría necesitado codificar octalmente el nombre del archivo.

Ángel
fuente
3

Puede encontrar este directorio en un administrador de archivos, por ejemplo, nautilus y simplemente arrástrelo y suéltelo en la terminal.

Si anteriormente escribiste cden la terminal, obtendrás el comando.

Piloto6
fuente
En realidad estoy tratando de hacer todo desde la terminal. :). Entonces no hay necesidad de pensar en el nautilus. Creo que debe haber un procedimiento para acceder al archivo. Como Linux siempre guarda un identificador único para un archivo en particular. Pero no sé cómo hacer eso o puede hacerse esto realmente.
Maruf
No está claro lo que preguntas. No es posible cambiar a un directorio que no ingrese su nombre de alguna manera.
Pilot6
Ver la declaración. Lo he actualizado
Maruf
O si este es el problema con un solo archivo, puede agregar un alias.
daltonfury42
1

No estoy seguro de si eso es exactamente lo que está pidiendo, pero zshtiene algunos trucos geniales para acceder a un directorio por otros medios que no sean escribir el nombre estricto del directorio; por un lado, puede escribir una parte del nombre y se expandirá al nombre completo del directorio, lo que permite cosas muy útiles, por ejemplo:

ingrese la descripción de la imagen aquí

Golpeando TAB...

ingrese la descripción de la imagen aquí

kos
fuente
1

La forma más simple es hacer doble clic en el nombre del directorio (suponiendo que esté visible en la pantalla), luego escriba cd seguido de espacio y haga clic en el botón de la rueda con el mouse y copiará y pegará el nombre del directorio que ha resaltado. Al presionar la tecla Intro, cambiará al directorio requerido.

Uso este procedimiento todo el tiempo y no solo se limita a los nombres de directorio. Se puede usar para cualquier comando que use la línea de comando.

Buena suerte.

Allen
fuente
Esto no escapará a los personajes especiales
Scz
1

Si es solo uno o unos pocos directorios, ¿por qué no tener alias en su bashrc o cualquier archivo de inicio? Por ejemplo:

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

Luego, cuando quieras ir allí, solo escribe abc

Saltando conejito
fuente
0

Puede escribir un programa para crear una tabla hash para todos los directorios de su sistema operativo. Básicamente sería un programa de aplanamiento de árboles.

Pero entonces podría hacer algo como hash-cd 32okjv02y haría la búsqueda de la tabla hash para la 32okjv02asignación del directorio. y salta a tu directorio. Y sería realmente rápido una vez que indexara todos sus directorios.

Tendría que usar el alias mkdir para llamar a este programa en cada directorio nuevo y tal vez escribir un comando de comprobación / actualización de tabla hash que pudiera cronometrar cada minuto y al iniciar sesión.

mutante_ciudad
fuente