Làm thế nào tôi có thể cd vào một thư mục mà không cần viết tên của nó?


8

Đôi khi thật khó chịu khi truy cập một thư mục có tên thư mục. Nói rằng tôi có một thư mục có tên a b c d. Ngoài việc sử dụng Tab, có cách nào để truy cập thư mục mà không cần gõ tên của thư mục không?

Tôi biết rằng Linux có một định danh duy nhất cho mỗi tệp cụ thể. Tôi có thể sử dụng điều này để truy cập vào thư mục? Tôi không biết liệu điều này thực sự có thể được thực hiện hay làm thế nào để làm điều đó.

Tôi nghĩ rằng khi Linux thực hiện một hệ thống tập tin, nó sẽ so sánh tính duy nhất của hai tên thư mục. Vì vậy, mỗi thư mục phải là duy nhất trong một không gian. Nhưng tôi nghĩ rằng nó giống như một khóa chính trong hệ thống cơ sở dữ liệu. Khóa chính có phải là tên của thư mục hay có một số định danh duy nhất khác (có thể là một số số được lưu trữ dưới tên hood hood)?

Hãy thử nghĩ về điều này giống như một quá trình. Nếu bạn thực thi lệnh pstrên một thiết bị đầu cuối, nó sẽ đưa ra một danh sách quy trình với tên và số của mỗi quy trình. Bạn phải gọi quy trình đó với số quy trình. Tương tự, có một số cho một thư mục để bạn có thể gọi thư mục đó bằng số của nó thay vì gọi nó với tên của nó?


Khi điều tra sâu hơn, tôi đã thấy rằng mỗi thư mục có một duy nhất inode. Tuy nhiên, cho đến nay tôi vẫn chưa tìm thấy bất kỳ lệnh tích hợp nào để truy cập vào một thư mục inode.


1
ký tự đại diện làm việc quá. nếu không thì cài đặt zshthay vìbash
Rinzwind 8/8/2015

Ok wildcards không phải là câu trả lời tôi tìm kiếm. cần suy nghĩ về zsh
Maruf

Bạn cần truy cập một thư mục như thế hoặc có nhiều?
Sergiy Kolodyazhnyy

Thêm giải pháp của bạn (có thể thú vị bằng cách này) như một câu trả lời thay vì thêm nó vào câu hỏi của bạn. Đó là những gì câu trả lời được thực hiện cho!
kos

Làm cho chương trình đó chỉ cần in đường dẫn và thực hiện cd $(icd XXXX)--- bạn chỉ cần viết lại findphần đó . Bây giờ nhiệm vụ tiếp theo của bạn là ... kiểm tra những gì hiệu quả hơn, chương trình của bạn hoặc find:-P.
Rmano

Câu trả lời:


2

Giải pháp được thực hiện bởi OP

Không có lệnh tích hợp nào được tìm thấy ở đây. Nhưng cuối cùng tôi có thể viết chương trình C để sử dụng cd (hãy gọi chương trình của tôi là icd == (inode cd)) để nhập vào một thư mục sử dụng giá trị inode. Ở đây tôi đang đăng mã thô.

Nhưng có một vấn đề cơ bản tôi đã phải đối mặt ở đây. Trong khi mã hóa thực thi mã C từ bash cần thiết để tạo tiến trình con theo quy trình bash (tiến trình cha). Từ tiến trình con, không gian thư mục là mới và tôi không thể truy cập không gian thư mục của tiến trình cha mẹ từ đó. Vì vậy, không có gì có thể được thực hiện ngoại trừ việc gọi một cửa sổ bash mới từ đây. Trong tương lai tôi sẽ cố gắng thực hiện một tính năng tab mới nếu mọi người quan tâm đến điều này. Nhưng tôi tin rằng tôi đã phải đối mặt với nhiều lời chỉ trích vì làm điều này. Vì vậy, mọi người có thể không quan tâm. Tôi vừa làm cho vui chơi của tôi.

Mã RAW được chia sẻ ở đây,

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

}

Tôi đang sử dụng thiết bị đầu cuối gnome ở đây. Rõ ràng Đối với các bản phân phối khác, mã sẽ được thay đổi.


1
Nếu bạn có thể di chuyển đến một thư mục trong tập lệnh shell, bạn có thể nguồn tập lệnh để thực hiện những gì bạn muốn. Việc xác định một bí danh để rút ngắn lệnh.
daltonfury42

19

Bất kỳ thực thể nào trong (hầu hết) các hệ thống tệp trên Linux đều có một định danh duy nhất được gọi là inode. Lưu ý rằng một tệp có thể có nhiều hơn một tên (liên kết cứng ), nhưng các thư mục chỉ có một liên kết trong tất cả các hệ thống tệp mà tôi biết. Lưu ý rằng khái niệm inode là cục bộ đối với hệ thống tập tin, do đó, trong hai thiết bị khác nhau (phân vùng hoặc bất cứ thứ gì), tính duy nhất không được đảm bảo.

Bạn có thể thấy inode của thư mục của bạn với ls -ldi:

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

Vì vậy, bạn biết rằng thư mục của bạn có inode 20873234. Bây giờ bạn có thể chuyển sang thư mục đó bằng lệnh:

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

(Lưu ý rằng việc 2> /dev/nulltắt các thông báo lỗi về các thư mục không thể đọc được dọc theo đường dẫn.)

Lệnh này sẽ quét toàn bộ thư mục nhà của bạn, vì vậy hãy kiên nhẫn. 1

Nhưng những gì về việc sử dụng cdvà hoàn thành TAB của vỏ của bạn?


1. Đây phải là 2 điều không hiệu quả nhất mà tôi từng đăng ... một cú hích cho entropy. Lý do là vì khóa chính của Cameron, trong đó quyền truy cập vào tệp hoặc thư mục được tối ưu hóa, nhanh và trực tiếp - hãy đoán xem? - tên đường dẫn :/dir/dir/file_or_dir. Hơn nữa, để cấp cho bạn quyền truy cập vào một thư mục nhất định, hệ thống cần kiểm tra tất cả các quyền trong đường dẫn ... vì vậy, một lần nữa, truy cập bằng inode có nghĩa là quét đệ quy hệ thống tệp.

2. Chà, bạn có thể làm mọi thứ tồi tệ hơn bằng cách quét từ/. 3

3. Nhưng sau đó, nó sẽ không hoạt động, bởi vì các nút chỉ là duy nhất trên cơ sở mỗi hệ thống tập tin (mỗi lần gắn).


Cảm ơn @Romano. Thật ra tôi đã suy nghĩ về vấn đề này. Tôi không biết rằng vấn đề sẽ biến thành giải pháp không hiệu quả như vậy. Nhưng hãy nghĩ về giải pháp. Bạn có thể dễ dàng viết chương trình ac và đặt nó vào / bin và sau đó thử thực hiện nó với số inode duy nhất. Tôi sẽ đăng mã nếu tôi có thể viết suy nghĩ như vậy.
Maruf

1
và cũng có một người nghĩ tôi cần biết. Tôi hiểu phần đầu tiên của lệnh này. "$ (tìm ~ -inum 20873234 ******)". nhưng tôi không biết tại sao bạn lại viết cái này, "2> / dev / null". Bạn có thể vui lòng làm rõ một lần nữa.
Maruf

4
@Maruf, nó sẽ không hoạt động, hiệu quả-khôn ngoan. Các "khóa chính", theo đó các quyền truy cập vào một tập tin hoặc thư mục được tối ưu hóa, nhanh chóng và trực tiếp là, đoán những gì, tên đường dẫn ... /dir/dir/file_or_dir. Chương trình C của bạn cũng sẽ cần quét hệ thống tập tin và findđã được tối ưu hóa trong 40 năm qua ... vẫn --- tại sao? Nếu bạn cần một phím tắt, sử dụng a="/my/really/strange and long/dir path name/"và sau đó cd "$a". Không thể đánh bại nó. Hoặc sử dụng symlink.
Rmano

1
Một cái tốt +1. Tôi đã ở rìa của việc viết một cái gì đó tương tự, nhưng tôi quá lười biếng, vì nhiệm vụ không có ý nghĩa gì cả. @Rmano
Pilot6 8/8/2015

3
@Rmano Tôi sẽ nói thêm rằng, nói chung, ngay cả trên một hệ thống tệp duy nhất, có thể có một số tệp có cùng một nút, tức là các liên kết cứng. Vì chúng ta đang nói về các thư mục ở đây, nên có một sự thật là mỗi thư mục có một nút duy nhất (các thư mục không thể được liên kết cứng.) Ngoài ra, tôi nghĩ rằng lý do mà người ta không thể truy cập trực tiếp vào tệp qua inode của nó là vì điều này sẽ bỏ qua bất kỳ thư mục nào truyền tải, cần thiết để xác định xem người dùng có được phép truy cập tài nguyên tương ứng hay không. (Vì vậy, nếu một thư mục có thể được truy cập bằng inode của nó, thì kernel sẽ phải xác định đường dẫn của nó.)
Malte Skoruppa

8

Bạn có thể thực hiện Tabxoay các thư mục có sẵn thay vì liệt kê chúng. Chỉnh sửa tập tin ~/.inputrcvà thêm

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

Nếu bạn muốn nó cho tất cả người dùng, /etc/inputrcthay vào đó hãy chỉnh sửa .

Nhấn Ctrl+ xCtrl+ rđể làm cho nó hiệu quả.

Bây giờ sử dụng cdTabđể điều hướng đến thư mục của bạn mà không cần viết tên của nó. cdShift+ Tabsẽ xoay theo hướng khác.

Đáng nhớ rằng cd -sẽ đưa bạn đến thư mục truy cập cuối cùng.


Đây là một câu trả lời tốt. Bạn có thể làm cho nó hiển thị một lần và sau đó xoay?
daltonfury42

1
Bạn có thể gán cái này cho một phím tắt khác. Tôi sử dụng Eclipse và tôi đã quen với Ctrl + dấu cách để tự động hoàn thành nên tôi sử dụng "\ C-": hoàn thành menu thay vào đó, để lại tab như vậy.
Katu

5

Bạn có thể sử dụng ký tự đại diện vỏ.

Chẳng hạn, tôi có thể làm

cd a?b?c?d

hoặc là

cd a\*b\*c\*d

Và nó sẽ mở rộng các ký tự đại diện thành tên thật và thay đổi thư mục đó. Giả sử đó là thư mục duy nhất phù hợp.

Nếu bạn có cả a b c da1b2c3d, sau đó cd a?b?c?dsẽ mở rộng cho một trong hai cd a1b2c3d a b c dhoặc cd a b c d a1b2c3d(thứ tự thực tế sẽ phụ thuộc vào hạt nhân, hệ thống tập tin ...), và bash âm thầm sẽ chuyển bạn đến con đường đầu tiên.

Mặt khác, bạn thường không có các thư mục được đặt tên tương tự nhau, vì vậy một cái gì đó giống như a*dlà đủ để mở rộng mà không cần phải nhập tất cả các ký tự trung gian. Điều này đặc biệt hữu ích khi bạn không thực sự có thể nhập nó (ví dụ: tên nằm trong một tập lệnh khác hoặc thậm chí là một mã hóa khác), và nếu không bạn sẽ cần phải mã hóa tên tệp.


3

Bạn có thể tìm thấy thư mục này trong trình quản lý tệp, ví dụ nautilus và chỉ cần kéo và thả nó vào thiết bị đầu cuối.

Nếu trước đây bạn gõ cdvào terminal, bạn sẽ nhận được lệnh.


Thật ra tôi đang cố gắng làm mọi thứ từ thiết bị đầu cuối. :). Vì vậy, không cần phải suy nghĩ về nautilus. Tôi nghĩ rằng phải có một thủ tục để truy cập vào tập tin. Vì Linux luôn lưu một mã định danh duy nhất cho một tệp cụ thể. Nhưng tôi không biết làm thế nào để làm điều đó hoặc điều này thực sự có thể được thực hiện.
Maruf

Không rõ những gì bạn yêu cầu. Không thể thay đổi thành một thư mục không nhập tên của nó theo một cách nào đó.
Pilot6

Xem tuyên bố. Tôi đã cập nhật nó.
Maruf

Hoặc nếu đây là vấn đề với một tệp duy nhất, bạn có thể thêm bí danh.
daltonfury42

1

Không chắc chắn nếu đó chính xác là những gì bạn yêu cầu, nhưng zshcó một số thủ thuật gọn gàng để truy cập vào một thư mục bằng các cách khác ngoài việc gõ tên nghiêm ngặt của thư mục; đối với một, bạn có thể nhập một phần của tên và nó sẽ mở rộng thành tên đầy đủ của thư mục, cho phép những thứ rất hữu ích, ví dụ:

nhập mô tả hình ảnh ở đây

Đánh TAB...

nhập mô tả hình ảnh ở đây


1

Cách đơn giản nhất là nhấp đúp chuột vào tên thư mục (giả sử nó hiển thị trên màn hình), sau đó nhập cd theo dấu cách và nhấp vào nút bánh xe trên chuột của bạn và nó sẽ sao chép và dán tên thư mục mà bạn đã tô sáng. Nhấn phím enter sau đó sẽ thay đổi thư mục yêu cầu.

Tôi sử dụng thủ tục này mọi lúc và nó không chỉ giới hạn trong tên thư mục. Nó có thể được sử dụng cho bất kỳ lệnh nào bằng cách sử dụng dòng lệnh.

Chúc may mắn.


Điều này sẽ không thoát khỏi các ký tự đặc biệt
Scz

1

Nếu nó chỉ là một hoặc một vài thư mục, tại sao không có bí danh trong bashrc của bạn hoặc bất kỳ tệp init nào? Ví dụ:

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

Sau đó, bất cứ khi nào bạn muốn đi vào đó, chỉ cần gõ abc


0

Bạn có thể viết chương trình để tạo bảng băm cho tất cả các thư mục HĐH của bạn. Về cơ bản nó sẽ là một chương trình làm phẳng cây.

Nhưng sau đó bạn có thể làm một cái gì đó như thế hash-cd 32okjv02và nó sẽ thực hiện tra cứu bảng băm cho 32okjv02ánh xạ thư mục. và nhảy đến thư mục của bạn. Và nó sẽ thực sự nhanh khi bạn đã lập chỉ mục tất cả các thư mục của mình.

Bạn sẽ phải bí danh mkdir để gọi chương trình này mỗi thư mục mới và có thể viết lệnh kiểm tra / làm mới bảng băm mà bạn có thể cron mỗi phút và đăng nhập.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.