名前を書かずにディレクトリに移動するにはどうすればよいですか?


8

時々、フォルダ名でディレクトリにアクセスするのは面倒です。という名前のディレクトリがあるとしa b c dます。を使用する以外Tabに、ディレクトリの名前を入力せずにフォルダにアクセスする方法はありますか?

Linuxには特定のファイルごとに一意の識別子があることを知っています。これを使用してフォルダにアクセスできますか?これが実際にできるのか、どうやって行うのかわかりません。

Linuxがファイルシステムを実装するとき、それは2つのディレクトリ名の一意性を比較すると思います。したがって、各ディレクトリはスペース内で一意である必要があります。しかし、それはデータベースシステムの主キーのようなものだと思います。主キーはディレクトリの名前ですか、それとも他の一意の識別子がありますか(おそらく「内部」に格納されているいくつかの番号)。

これをプロセスのように考えてみてください。ps端末でコマンドを実行すると、各プロセスの名前と番号を含むプロセスリストが出力されます。そのプロセスをプロセス番号で呼び出す必要があります。同様に、名前で呼び出すのではなく、番号でディレクトリを呼び出すことができるように、ディレクトリには番号がありますか?


さらに調査したところ、各ディレクトリに固有のがあることがわかりましたinode。ただし、これまでのところ、そのによってディレクトリにアクセスするための組み込みコマンドは見つかりませんでしたinode


1
ワイルドカードも機能します。それ以外の場合は、zsh代わりにインストールbash
Rinzwind

わかりましたワイルドカードは私が求める答えではありません。zshについて考える必要がある
Maruf、2015

あなたはそのような1つのディレクトリにアクセスする必要があるか、複数ありますか?
Sergiy Kolodyazhnyy 2015

質問に追加するのではなく、回答としてソリューション(ちなみに興味深いかもしれません)を回答として追加します。それが答えの為です!
2015

そのプログラムにパスを出力させてcd $(icd XXXX)---あなたはそのfind部分を書き直しました。次のタスクは...プログラムまたはfind:-Pのどちらがより効率的かを確認します。
Rmano 2015

回答:


2

OPによるソリューション

ここには組み込みコマンドはありません。しかし、最後にcdを使用してCプログラムを記述し、(inode値を使用してicd ==(inode cd)を呼び出す)フォルダーに入ることができます。ここで生のコードを投稿しています。

しかし、私がここで直面した根本的な問題があります。実行のコーディング中に、bashプロセス(親プロセス)の下に子プロセスを作成するために必要なbashからのCコード。子プロセスからディレクトリスペースは新しく、そこから親プロセスのディレクトリスペースにアクセスできません。したがって、ここから新しい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 2015

19

Linuxの(ほとんどの)ファイルシステムのエンティティには、と呼ばれる一意の識別子がありinodeます。ファイルには複数の名前(hardlink)を付けることができますが、ディレクトリには、私が知っているすべてのファイルシステムで1つのリンクしかありません。inodeの概念はファイルシステムに対してローカルであるため、2つの異なるデバイス(パーティションなど)では一意性が保証されないことに注意してください。

あなたはあなたのディレクトリのinodeを見ることができますls -ldi

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

これで、ディレクトリにiノード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.しかし、iノードはファイルシステム(マウント)ごとにのみ一意であるため、機能しません。


@Romanoに感謝します。実際、私はその問題について考えていました。問題がこのような非効率的な解決策になるかどうかはわかりません。しかし、解決策について考えてください。acプログラムを簡単に作成して/ binに入れ、iノード番号のみで実行することができます。そのような考えが書けたら、コードを掲載します。
Maruf

1
また、私が知る必要があると思います。このコマンドの最初の部分を理解しました。"$(find〜-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"ます。それを倒すことはできません。またはシンボリックリンクを使用します。
Rmano

1
良いもの+1。私は似たようなものを書くのはぎりぎりでしたが、その仕事はまったく意味がないので、私はあまりにも怠惰でした。@Rmano
Pilot6

3
@Rmano一般的に、単一のファイルシステムであっても、同じiノードを持つ複数のファイル、つまりハードリンクがある可能性があることを追加します。ここではディレクトリについて説明しているため、各ディレクトリに一意のiノードがあることは事実です(ディレクトリはハードリンクできません)。また、iノードを介してファイルに直接アクセスできないのは、これによりディレクトリがバイパスされるためです。トラバーサル。ユーザーが対応するリソースへのアクセスを許可されているかどうかを判別するために必要です。(そのため、iノードからディレクトリにアクセスできる場合は、カーネルはとにかくそのパスを決定する必要があります。)
Malte Skoruppa

8

Tabリストを表示する代わりに、使用可能なフォルダをローテーションさせることができます。ファイル~/.inputrcを編集して追加

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

すべてのユーザーに適用する場合は、/etc/inputrc代わりに編集してください。

Ctrl+ xCtrl+ rを押して有効にします。

次に、を使用cdTabして、名前を書き込まずにフォルダに移動します。cdShift+ Tabは反対方向に回転します。

cd -最後にアクセスしたフォルダに移動することを覚えておく価値があります。


これは良い答えです。一度表示させてから回転させることはできますか?
daltonfury42 2015

1
これを別のショートカットに割り当てることができます。私はEclipseを使用していて、オートコンプリートのCtrl +スペースに慣れているので、代わりに "\ C-":menu-completeを使用して、タブをそのままにします。
Katu

5

シェルのワイルドカードを使用できます。

たとえば、私はすることができます

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、中間の文字をすべて入力しなくても、フォルダを拡張するのに十分です。これは、実際に入力できない場合(たとえば、名前が別のスクリプトまたは別のエンコーディングにある場合など)に特に役立ちます。そうでなければ、ファイル名を8進エンコードする必要がありました。


3

このディレクトリは、nautilusなどのファイルマネージャで見つけることができ、ターミナルにドラッグアンドドロップするだけです。

以前cdにターミナルに入力した場合は、コマンドが表示されます。


実際、私は端末からすべてをしようとしています。:)。したがって、ノーチラスについて考える必要はありません。ファイルにアクセスする手順が必要だと思います。Linuxは常に特定のファイルの一意の識別子を保存するため。しかし、私はそれを行う方法がわかりません、またはこれを実際に行うことができます。
Maruf

あなたが何を尋ねるかは不明確です。何らかの方法で名前を入力していないディレクトリに変更することはできません。
Pilot6 2015

ステートメントを参照してください。更新しました。
Maruf、

または、これが単一ファイルの問題である場合は、エイリアスを追加できます。
daltonfury42 2015

1

それがまさにあなたが求めていることかどうかはわかりませんがzsh、ディレクトリの厳密な名前を入力する以外の方法でディレクトリにアクセスするための巧妙なトリックがいくつかあります。たとえば、名前の一部を入力すると、ディレクトリの完全な名前に展開されるため、次のような非常に便利なことが可能になります。

ここに画像の説明を入力してください

打つTAB...

ここに画像の説明を入力してください


1

最も簡単な方法は、ディレクトリ名をダブルクリックし(画面に表示されている場合)、cdの後にスペースを入力し、マウスのホイールボタンをクリックすると、強調表示したディレクトリ名がコピーされて貼り付けられます。Enterキーを押すと、必要なディレクトリに移動します。

私はこの手順をいつも使用しており、ディレクトリ名だけに限定されていません。コマンドラインを使用するすべてのコマンドに使用できます。

幸運を。


これは特殊文字をエスケープしません
Scz

1

それが1つまたはいくつかのディレクトリである場合、bashrcまたはその他のinitファイルにエイリアスを設定しないのはなぜですか?例えば:

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

そこに行きたいときはいつでも abc


0

すべてのOSディレクトリのハッシュテーブルを作成するプログラムを作成できます。基本的には、木の平坦化プログラムです。

しかし、あなたは次のようなhash-cd 32okjv02ことをすることができ、それは32okjv02ディレクトリマッピングへのハッシュテーブルルックアップを行います。ディレクトリにジャンプします。そして、すべてのディレクトリにインデックスを作成すると、本当に高速になります。

このプログラムを新しいディレクトリごとに呼び出すためにmkdirにエイリアスを設定し、ハッシュテーブルのチェック/更新コマンドを作成して、毎分およびログオン時にcronを実行する必要があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.