OP 提出的解决方案

OP 提出的解决方案

有时使用文件夹名称访问目录很烦人。假设我有一个名为 的目录a b c d。除了使用Tab,还有其他方法可以访问该文件夹而无需输入目录名称吗?

我知道 Linux 为每个特定文件都设置了唯一的标识符。我可以使用它来访问文件夹吗?我不知道这是否真的可以做到或如何做到。

我认为当 Linux 实现文件系统时,它会比较两个目录名称的唯一性。因此每个目录在空间中必须是唯一的。但我认为这就像数据库系统中的主键。主键是姓名目录还是有其他一些唯一标识符(也许是一些存储在“引擎盖下”的数字)?

试着将其想象成一个进程。如果您ps在终端上执行该命令,它会输出一个进程列表,其中包含每个进程的名称和编号。您必须使用进程编号来调用该进程。同样,目录是否有编号,以便您可以使用其编号来调用目录,而不是使用其名称来调用它?


经过进一步研究,我发现每个目录都有一个唯一的inode。但是,到目前为止,我还没有找到任何内置命令可以通过其访问目录inode

答案1

Linux 上 (大多数) 文件系统中的任何实体都有一个唯一标识符,称为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

但是如何使用cdshell 的 TAB 补全功能呢?


1.这肯定是我发过的最没有效率的东西了……这是对熵的颂歌。原因是,优化、快速和直接访问文件或目录的“主键”是——猜猜是什么?——路径名:/dir/dir/file_or_dir。此外,要授予您对给定目录的访问权限,系统需要检查路径中的所有权限……因此,再次强调,通过 inode 访问意味着递归扫描文件系统。

2.好吧,如果你从 扫描,情况会变得更糟/。3

3.但这样就行不通了,因为 inode 仅在每个文件系统(每个挂载)的基础上才是唯一的。

答案2

您可以Tab轮播可用文件夹,而不是列出它们。编辑文件~/.inputrc并添加

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

如果您希望所有用户都使用,/etc/inputrc请进行编辑。

Ctrl+xCtrl+r使其生效。

现在使用cdTab它导航到您的文件夹而无需写其名称。cdShift+Tab将向另一个方向旋转。

值得记住的是,它将cd -带您进入最后访问的文件夹。

答案3

您可以使用 shell 通配符。

例如,我可以做

cd a?b?c?d

或者

cd a\*b\*c\*d

它会将通配符扩展为实际名称并转到该目录。假设这是唯一匹配的目录。

如果同时拥有a b c da1b2c3d,那么cd a?b?c?d将扩展为cd a1b2c3d a b c dcd a b c d a1b2c3d(实际顺序取决于内核、文件系统……),并且 bash 将默默地将您移动到第一个路径。

另一方面,您通常没有名称如此相似的文件夹,因此类似这样的内容a*d足以扩展它,而无需键入所有中间字符。这在您实际上无法键入它时特别有用(例如,名称采用不同的脚本,甚至不同的编码),否则您将需要对文件名进行八进制编码。

答案4

OP 提出的解决方案

此处未找到内置命令。但最终我能够编写一个 C 程序来使用 cd(让我将我的程序称为 icd == (inode cd) )使用 inode 值进入文件夹。我在这里发布原始代码。

但是我在这里遇到了一个根本问题。在编写执行 Bash 中的 C 代码时,需要在 Bash 进程(父进程)下创建子进程。从子进程开始,目录空间是新的,我无法从那里访问父进程的目录空间。所以除了从这里调用一个新的 Bash 窗口外,什么也做不了。如果人们对此感兴趣,我将来会尝试实现一个新的选项卡功能。但我相信我这样做会招致很多批评。所以人们可能不感兴趣。我只是为了好玩才这么做的。

原始代码在此处共享,

#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 终端。显然对于其他发行版,代码将会改变。

相关内容