Mar*_*ruf 8 command-line files cd-command
有时访问具有文件夹名称的目录很烦人。假设我有一个名为a b c d. 除了使用 之外Tab,还有什么方法可以在不输入目录名称的情况下访问该文件夹?
我知道 Linux 每个特定文件都有一个唯一标识符。我可以用它来访问文件夹吗?我不知道这是否可以真正做到或如何做到。
我认为当 Linux 实现一个文件系统时,它会比较两个目录名称的唯一性。所以每个目录在一个空间中必须是唯一的。但我认为它就像数据库系统中的主键。主键是目录的名称还是有其他一些唯一标识符(也许是一些存储在“引擎盖下”的数字)?
试着把这想象成一个过程。如果ps在终端上执行该命令,它会输出一个进程列表,其中包含每个进程的名称和编号。您必须使用进程号调用该进程。同样,目录是否有号码,以便您可以用号码呼叫目录而不是用名称呼叫?
在进一步调查中,我发现每个目录都有一个唯一的inode. 但是,到目前为止,我还没有找到任何内置命令来通过其inode.
Rma*_*ano 19
Linux 上(大多数)文件系统中的任何实体都有一个唯一标识符,称为inode. 请注意,一个文件可以有多个名称(hardlink),但目录在我所知道的所有文件系统中只有一个链接。请注意,inode 的概念是文件系统的本地概念,因此在两个不同的设备(分区或其他)中,不能保证唯一性。
您可以使用以下命令查看目录的 inode ls -ldi:
[:~] % ls -ldi tmp/uffa
20873234 drwxrwxr-x 2 romano romano 4096 Jun 26 2014 tmp/uffa
Run Code Online (Sandbox Code Playgroud)
所以你知道你的目录有 inode 20873234。现在你可以使用命令切换到它:
[:~] % cd "$(find ~ -inum 20873234 2> /dev/null)"
[:~/tmp/uffa] %
Run Code Online (Sandbox Code Playgroud)
(请注意,这2> /dev/null是关闭路径中有关不可读目录的错误消息。)
此命令将扫描您的整个主目录,因此请耐心等待。1
但是如何使用cdshell 和 TAB 完成呢?
1.这一定是我发布过的最无效率的2件事……一首熵的颂歌。原因是对文件或目录的访问被优化、快速和直接的“主键”是——你猜怎么着?— 路径名:/dir/dir/file_or_dir。此外,要授予您对给定目录的访问权限,系统需要检查路径中的所有权限……同样,通过 inode 访问意味着递归扫描文件系统。
2.好吧,您可以通过从 扫描来使事情变得更糟/。3
3.但是这样就行不通了,因为 inode 仅在每个文件系统(每个挂载)的基础上是唯一的。
您可以Tab旋转可用文件夹而不是列出它们。编辑文件~/.inputrc并添加
"\C-i": menu-complete
"\e[Z": "\e-1\C-i"
Run Code Online (Sandbox Code Playgroud)
如果您希望所有用户都使用它,请/etc/inputrc改为编辑。
按Ctrl+x和Ctrl+r使其生效。
现在用于cdTab导航到您的文件夹而不写其名称。cdShift+Tab将向另一个方向旋转。
值得记住的是,这cd -会将您带到上次访问的文件夹。
您可以使用 shell 通配符。
例如,我可以做
cd a?b?c?d
Run Code Online (Sandbox Code Playgroud)
或者
cd a\*b\*c\*d
Run Code Online (Sandbox Code Playgroud)
它会将通配符扩展为实际名称并更改为该目录。假设这是唯一匹配的目录。
如果您同时拥有a b c dand a1b2c3d,cd a?b?c?d则将扩展为cd a1b2c3d a b c dor cd a b c d a1b2c3d(实际顺序将取决于内核、文件系统...),并且 bash 会默默地将您移动到第一个路径。
另一方面,您通常没有名称如此相似的文件夹,因此类似的a*d内容足以扩展它而无需键入所有中间字符。当您实际上无法键入它时(例如,名称在不同的脚本中,甚至不同的编码),这特别有用,否则您将需要对文件名进行八进制编码。
此处未找到内置命令。但最终我能够编写一个 C 程序来使用 cd (让我们调用我的程序 icd == (inode cd) )使用 inode 值进入文件夹。我在这里发布原始代码。
但我在这里遇到了一个根本问题。在从 bash 编码执行 C 代码时,需要在 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 ;
}
Run Code Online (Sandbox Code Playgroud)
我在这里使用 gnome 终端。显然对于其他发行版,代码将被更改。