Як я можу записатись на каталог без написання його імені?


8

Іноді дратує доступ до каталогу з назвою папки. Скажіть, у мене є каталог з іменем a b c d. Окрім використання Tab, чи є якийсь спосіб отримати доступ до папки без введення імені каталогу?

Я знаю, що Linux має унікальний ідентифікатор кожного конкретного файлу. Чи можу я використовувати це для доступу до папки? Я не знаю, чи можна це зробити насправді чи як це зробити.

Я думаю, коли Linux реалізує файлову систему, вона порівнює унікальність двох імен каталогів. Отже, кожен каталог повинен бути унікальним у просторі. Але я думаю, що це як первинний ключ у системі баз даних. Чи є первинний ключ ім'ям каталогу чи є якийсь інший унікальний ідентифікатор (можливо, деякі цифри зберігаються "під капотом")?

Спробуйте думати про це як про процес. Якщо ви виконуєте команду psна терміналі, вона виводить список процесів із назвою та номером кожного процесу. Ви повинні викликати цей процес з номером процесу. Аналогічно, чи є номер для каталогу, щоб ви могли зателефонувати до каталогу з його номером, а не називати його своїм ім'ям?


При подальшому дослідженні я виявив, що кожен каталог має унікальний характер inode. Однак я поки що не знайшов жодної вбудованої команди для доступу до каталогу за її допомогою inode.


1
wildcards також працюють. інакше встановіть zshзамістьbash
Rinzwind

Гаразд, малі знаки - це не відповідь, яку я прагну. потрібно подумати про zsh
Маруф

Вам потрібно отримати доступ до одного такого каталогу чи їх кілька?
Сергій Колодяжний

Додайте своє рішення (яке, до речі, може бути цікавим) як відповідь, замість того, щоб додавати його до свого питання. Ось для чого і відповіді!
kos

Зробіть так, щоб програма просто надрукувала шлях і зробіть cd $(icd XXXX)--- ви просто переписали цю findчастину. Тепер ваше наступне завдання - перевірити, що більш ефективно, ваша програма чи find:-P.
Рмано

Відповіді:


2

Рішення прийняте ОП

Тут не знайдено вбудованої команди. Але нарешті я можу написати програму 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 ;

}

Я тут використовую термінал gnome. Очевидно, що для інших дистрибутивів код буде змінено.


1
Якщо ви могли перейти до каталогу в сценарії оболонки, ви можете джерелом сценарію виконати те, що ви хочете. Визначте псевдонім для скорочення команди.
daltonfury42

19

Будь-яка суть у (більшості) файлових систем в Linux має унікальний ідентифікатор, який називається an inode. Зауважте, що файл може мати більше одного імені ( жорстке посилання ), але каталоги мають лише одне посилання у всіх файлових системах, про які я знаю. Зауважте, що поняття inode є локальним для файлової системи, так що в двох різних пристроях (розділі чи будь-якому іншому) унікальність не гарантується.

Ви можете побачити inode вашого каталогу за допомогою ls -ldi:

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

Отже, ви знаєте, що ваш каталог має inode 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. Але тоді це не буде працювати, оскільки введення є унікальним лише на основі файлової системи (на монтування).


Дякую @Romano Власне, я думав над проблемою. Я не знаю, що проблема перетвориться на таке неефективне рішення. Але подумайте про рішення. Ви можете легко написати програму змінного струму і ввести її в / bin, а потім спробувати виконати її з єдиним номером inode. Я опублікую код, якщо зможу написати таку думку.
Маруф

1
а також одна думка, яку мені потрібно знати. Я розумію першу частину цієї команди. "$ (знайти ~ -inum 20873234 ******)". але я не знаю, чому ви пишете це "2> / dev / null". Ви можете, будь ласка, уточнити ще раз.
Маруф

4
@Maruf, це не буде працювати, ефективніше. «Первинний ключ» , при якому доступ до файлу або каталогу оптимізований, швидко і надійно є, думаю , що, в дорогу ... /dir/dir/file_or_dir. Ваша програма C також потребує сканування файлової системи, і findвона була оптимізована протягом останніх 40 років ... все ж --- чому? Якщо вам потрібен ярлик, скористайтесь a="/my/really/strange and long/dir path name/"і потім cd "$a". Неможливо його перемогти. Або використовувати символьні посилання.
Рмано

1
Хороший +1. Я був на краю написання чогось подібного, але я був занадто ледачий, оскільки завдання взагалі не має сенсу. @Rmano
Pilot6

3
@Rmano Я додам, що загалом навіть у одній файловій системі може бути декілька файлів, які мають однаковий inode, тобто жорсткі посилання. Оскільки ми говоримо про каталоги тут, трапляється, що кожен каталог має унікальний inode (каталоги не можуть бути жорстко пов’язані.) Крім того, я думаю, що причина, через яку не можна безпосередньо отримати доступ до файлу через його inode, полягає в тому, що це обійде будь-який каталог обхід, необхідний для визначення можливості доступу користувача до відповідного ресурсу. (Отже, якщо до каталогу можна було отримати доступ до його 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-": меню-завершення замість цього, залишаючи вкладку, як є.
Кату

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термінал, ви отримаєте команду.


Насправді я намагаюся робити все з терміналу. :). Тож не треба думати про наутілус. Я думаю, що має бути процедура доступу до файлу. Оскільки Linux завжди зберігає унікальний ідентифікатор для певного файлу. Але я не знаю, як це зробити чи це можна зробити насправді.
Маруф

Незрозуміло, що ви просите. Неможливо змінити каталог, не вводячи його ім’я якось.
Пілот6

Дивіться заяву. Я оновив його.
Маруф

Або якщо це проблема з одним файлом, ви можете додати псевдонім.
daltonfury42

1

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

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

Удар TAB...

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


1

Найпростіший спосіб - це двічі клацнути ім'я каталогу (припустимо, що воно видно на екрані), потім введіть cd, а потім пробіл, і натисніть кнопку колеса на миші, і він скопіює та вставить назву каталогу, яку ви виділили. Якщо натиснути клавішу введення, то зміниться на потрібний каталог.

Я постійно використовую цю процедуру, і вона не обмежується лише іменами каталогу. Його можна використовувати для будь-яких команд, що використовують командний рядок.

Удачі.


Цьому не вдасться уникнути особливих персонажів
сц

1

Якщо це лише один або декілька каталогів, чому б не мати псевдонімів у вашому файлі bashrc або будь-яких файлів init? Наприклад:

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

Тоді, коли ви хочете зайти туди, просто введіть abc


0

Ви можете написати програму для створення хеш-таблиці для всіх ваших каталогів ОС. Це, в основному, програма вирівнювання дерев.

Але тоді ви можете зробити щось на кшталт, hash-cd 32okjv02і це зробить пошук хеш-таблиці для 32okjv02відображення каталогу в каталог. і перейти до каталогу. І було б дуже швидко, як тільки ви індексували всі ваші каталоги.

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.