Как я могу перейти в каталог без записи его имени?

8

Иногда раздражает доступ к каталогу с именем папки. Скажем, у меня есть каталог с именем a b c d. Помимо использования Tab, есть ли способ получить доступ к папке без ввода имени каталога?

Я знаю, что у Linux есть уникальный идентификатор для каждого конкретного файла. Могу ли я использовать это для доступа к папке? Я не знаю, можно ли это сделать на самом деле или как это сделать.

Я думаю, что когда Linux реализует файловую систему, он сравнивает уникальность двух имен каталогов. Таким образом, каждый каталог должен быть уникальным в пространстве. Но я думаю, что это как первичный ключ в системе баз данных. Является ли первичный ключ именем каталога или существует какой-то другой уникальный идентификатор (возможно, некоторые числа хранятся «под капотом»)?

Попробуйте думать об этом как о процессе. Если вы выполняете команду psна терминале, он выводит список процессов с именем и номером каждого процесса. Вы должны вызвать этот процесс с номером процесса. Точно так же, есть ли номер для каталога, чтобы вы могли вызывать каталог с его номером вместо того, чтобы называть его по имени?


При дальнейшем расследовании я обнаружил, что каждый каталог имеет уникальный inode. Тем не менее, я до сих пор не нашел ни одной встроенной команды для доступа к каталогу inode.

Маруф
источник
1
подстановочные знаки тоже работают. в противном случае установите zshвместоbash
Rinzwind
Хорошо, подстановочные знаки - это не ответ, который я ищу. нужно думать о зш
Маруф
Вам нужно получить доступ к одному каталогу, как это или несколько?
Сергей Колодяжный
Добавьте свое решение (что, кстати, может быть интересно) в качестве ответа, а не добавляйте его к своему вопросу. Вот для чего сделаны ответы!
Кос
Заставьте эту программу просто напечатать путь и сделайте cd $(icd XXXX)--- вы просто переписали эту findчасть. Теперь ваша следующая задача ... проверить, что более эффективно, ваша программа или find:-P.
Rmano

Ответы:

2

Решение от OP

Здесь не найдена встроенная команда. Но, наконец, я могу написать C-программу для использования cd (давайте вызовем мою программу icd == (inode cd)) для входа в папку с использованием значения inode. Здесь я размещаю сырой код.

Но есть фундаментальная проблема, с которой я столкнулся здесь. При выполнении кодирования C-код из bash необходим для создания дочернего процесса в bash-процессе (родительском процессе). От дочернего процесса пространство каталога новое, и я не могу получить доступ к пространству каталога родительского процесса оттуда. Так что ничего нельзя было сделать, кроме как вызвать новое окно bash отсюда. В будущем я постараюсь реализовать новую функцию вкладок, если люди заинтересованы в этом. Но я считаю, что я столкнулся с большой критикой за это. Таким образом, люди могут быть не заинтересованы. Я только что сделал для моего развлечения.

RAW код доступен здесь,

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

}

Я использую терминал гнома здесь. Очевидно, что для других дистрибутивов код будет изменен.

Pilot6
источник
1
Если вы можете перейти в каталог внутри сценария оболочки, вы можете использовать сценарий для выполнения того, что вы хотите. Определите псевдоним, чтобы сократить команду.
daltonfury42
19

Любой объект в (большинстве) файловых систем в Linux имеет уникальный идентификатор, называемый inode. Обратите внимание, что файл может иметь более одного имени ( жесткая ссылка), но каталоги имеют только одну ссылку во всех файловых системах, о которых я знаю. Обратите внимание, что концепция inode является локальной для файловой системы, поэтому уникальность двух разных устройств (разделов и т. Д.) Не гарантируется.

Вы можете увидеть индекс вашего каталога с помощью ls -ldi:

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

Итак, вы знаете, что в вашем каталоге есть индекс 20873234. Теперь вы можете переключиться на него с помощью команды:

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

(Обратите внимание, что 2> /dev/nullэто закрывает сообщения об ошибках о нечитаемых каталогах по пути.)

Эта команда просканирует весь ваш домашний каталог, так что наберитесь терпения. 1

Но как насчет использования cdи TAB-завершения вашей оболочки?


1. Это должно быть наиболее 2 неэффективен вещькоторую я когдалибо писал ... ода энтропии. Причина в том, что «первичный ключ», по которому доступ к файлу или каталогу оптимизирован, быстрый и прямой, - угадайте, что? - имя пути:/dir/dir/file_or_dir. Более того, чтобы предоставить вам доступ к определенному каталогу, система должна проверить все разрешения в пути ... так что, опять же, доступ через inode означает рекурсивное сканирование файловой системы.

2. Ну, вы можете сделать хуже, отсканировав из/. 3

3. Но тогда это не будет работать, потому что inode уникальны только для файловой системы (для монтирования).

Rmano
источник
Спасибо @Romano. На самом деле я думал о проблеме. Я не знаю, что проблема превратилась бы в такое неэффективное решение. Но подумайте о решении. Вы можете легко написать программу ac и поместить ее в / bin, а затем попытаться выполнить ее с единственным номером inode. Я выложу код, если смогу написать такую ​​мысль.
Маруф
1
а также один думаю, что мне нужно знать. Я понимаю первую часть этой команды. "$ (найти ~ -inum 20873234 ******)". но я не знаю, почему вы пишете это, "2> / dev / null". Можете ли вы уточнить еще раз.
Маруф
4
@ Маруф, это не будет работать, с точки зрения эффективности. «Первичный ключ», по которому доступ к файлу или каталогу оптимизирован, быстрый и прямой - это, наверное, путь… /dir/dir/file_or_dir. Вашей C-программе тоже нужно будет сканировать файловую систему, и findона была оптимизирована в течение последних 40 лет ... до сих пор - почему? Если вам нужен ярлык, используйте a="/my/really/strange and long/dir path name/"и затем cd "$a". Не могу победить. Или используйте символические ссылки.
Rmano
1
Хороший +1. Я был на грани написания чего-то подобного, но мне было лень, так как задача вообще не имеет смысла. @Rmano
Pilot6
3
@Rmano Я бы добавил, что в целом даже в одной файловой системе может быть несколько файлов с одинаковым индексом, т. Е. Жесткие ссылки. Поскольку мы говорим о каталогах здесь, это правда, что каждый каталог имеет уникальный инод (каталоги не могут быть жестко связаны.) Кроме того, я думаю, что причина того, что нельзя напрямую получить доступ к файлу через его инод, заключается в том, что это обойдёт любой каталог обход, необходимый для определения, разрешен ли пользователю доступ к соответствующему ресурсу. (Так что, если к каталогу можно получить доступ по его inode, ядру все равно придется определить его путь.)
Malte Skoruppa
8

Вы можете Tabвращать доступные папки вместо того, чтобы перечислять их. Отредактируйте файл ~/.inputrcи добавьте

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

Если вы хотите это для всех пользователей, отредактируйте /etc/inputrcвместо этого.

Нажмите Ctrl+ xи Ctrl+, rчтобы сделать его эффективным.

Теперь используйте cdTabдля перехода к вашей папке, не записывая ее имя. cdShift+ Tabбудет вращаться в другом направлении.

Стоит помнить, что cd -вы попадете в последнюю посещенную папку.

Кату
источник
Это хороший ответ. Можете ли вы сделать так, чтобы он отображался один раз, а затем вращался?
daltonfury42
1
Вы можете назначить это другому ярлыку. Я использую Eclipse, и я привык к Ctrl + пробел для автозаполнения, поэтому вместо этого я использую "\ C-": menu-complete, оставляя tab как есть.
Кату
5

Вы можете использовать подстановочные знаки оболочки.

Например, я могу сделать

cd a?b?c?d

или

cd a\*b\*c\*d

И это расширит подстановочные знаки до фактического имени и изменится на этот каталог. Предполагая, что это единственный каталог, который соответствует.

Если у вас есть оба, a b c dи a1b2c3d, то cd a?b?c?dрасширится до одного cd a1b2c3d a b c dили cd a b c d a1b2c3d(фактический порядок будет зависеть от ядра, файловой системы ...), и bash молча перенесет вас на первый путь.

С другой стороны, у вас часто нет папок с одинаковыми именами, поэтому a*dдостаточно расширить что- то подобное , чтобы не вводить все промежуточные символы. Это особенно полезно, когда вы на самом деле не можете набрать его (например, имена находятся в другом скрипте или даже в другой кодировке), и в противном случае вам бы пришлось восьмерично кодировать имя файла.

Анхель
источник
3

Вы можете найти этот каталог в файловом менеджере, например, nautilus и просто перетащить его в терминал.

Если вы ранее набрали cdв терминале, вы получите команду.

Pilot6
источник
На самом деле я пытаюсь сделать все из терминала. :). Так что не нужно думать о наутилусе. Я думаю, что должна быть процедура для доступа к файлу. В Linux всегда сохраняют уникальный идентификатор для конкретного файла. Но я не знаю, как это сделать или это можно сделать на самом деле.
Маруф
Неясно, что вы спрашиваете. Невозможно перейти в каталог, не введя его имя каким-либо образом.
Pilot6
Смотрите заявление. Я обновил это.
Маруф
Или, если это проблема с одним файлом, вы можете добавить псевдоним.
daltonfury42
1

Не уверен, что это именно то, о чем вы просите, но zshесть некоторые хитрые приемы для доступа к каталогу другими способами, чем ввод строгого имени каталога; например, вы можете ввести часть имени, и оно расширится до полного имени каталога, что позволяет делать очень полезные вещи, например:

введите описание изображения здесь

Удар TAB...

введите описание изображения здесь

кос
источник
1

Самый простой способ - дважды щелкнуть имя каталога (при условии, что оно видно на экране), затем введите cd, затем пробел и нажмите кнопку колесика на вашей мыши, и он скопирует и вставит выделенное вами имя каталога. Нажатие клавиши ввода изменится на требуемый каталог.

Я использую эту процедуру все время, и она не ограничивается только именами каталогов. Может использоваться для любых команд, использующих командную строку.

Удачи.

Аллен
источник
Это не ускользнет от специальных символов
Scz
1

Если это просто один или несколько каталогов, почему бы не иметь псевдонимы в вашем bashrc или любых других файлах инициализации? Например:

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

Тогда всякий раз, когда вы хотите пойти туда, просто введите abc

Прыгающий кролик
источник
0

Вы можете написать программу для создания хеш-таблицы для всех ваших каталогов ОС. В основном это будет программа выравнивания деревьев.

Но тогда вы могли бы сделать что-то вроде этого, hash-cd 32okjv02и он сделал бы поиск по хеш-таблице для 32okjv02отображения в каталог. и перейти к вашему каталогу. И это будет очень быстро, как только вы каталогизируете все свои каталоги.

Вам нужно было бы использовать псевдоним mkdir для вызова этой программы в каждом новом каталоге и, возможно, написать команду проверки / обновления хеш-таблицы, которую вы могли бы выполнять каждую минуту и ​​при входе в систему.

mutant_city
источник