Como posso cd para um diretório sem escrever seu nome?

8

Às vezes, é irritante acessar um diretório com o nome da pasta. Digamos que eu tenha um diretório chamado a b c d. Além de usar Tab, existe alguma maneira de acessar a pasta sem digitar o nome do diretório?

Eu sei que o Linux tem um identificador único para cada arquivo em particular. Posso usar isso para acessar a pasta? Não sei se isso pode realmente ser feito ou como fazê-lo.

Eu acho que quando o Linux implementa um sistema de arquivos, ele compara a exclusividade de dois nomes de diretório. Portanto, cada diretório deve ser exclusivo em um espaço. Mas acho que é como uma chave primária em um sistema de banco de dados. A chave primária é o nome do diretório ou existe algum outro identificador exclusivo (talvez alguns números armazenados "sob o capô")?

Tente pensar nisso como um processo. Se você executar o comando psem um terminal, ele exibirá uma lista de processos com o nome e o número de cada processo. Você precisa chamar esse processo com o número do processo. Da mesma forma, existe um número para um diretório para que você possa chamá-lo com seu número em vez de chamá-lo com seu nome?


Em uma investigação mais aprofundada, descobri que cada diretório tem um único inode. No entanto, ainda não encontrei nenhum comando interno para acessar um diretório por ele inode.

Maruf
fonte
1
os curingas também funcionam. caso contrário, instale em zshvez debash
Rinzwind 8/08
Ok curingas não é a resposta que eu procuro. precisa pensar sobre zsh
Maruf
Você precisa acessar um diretório como esse ou há vários?
Sergiy Kolodyazhnyy 9/08/2015
Adicione sua solução (que pode ser interessante por sinal) como resposta, em vez de adicioná-la à sua pergunta. É para isso que as respostas são feitas!
kos
Faça com que o programa apenas imprima o caminho e faça cd $(icd XXXX)--- você acabou de reescrever essa findparte. Agora sua próxima tarefa é ... verifique o que é mais eficiente, seu programa ou find:-P.
Rmano

Respostas:

2

Solução feita pelo OP

Nenhum comando interno encontrado aqui. Mas, finalmente, sou capaz de escrever um programa em C para usar o cd (vamos chamar meu programa icd == (inode cd)) para entrar em uma pasta usando o valor do inode. Aqui estou postando o código bruto.

Mas há um problema fundamental que enfrentei aqui. Ao codificar a execução, um código C a partir de um bash precisava criar um processo filho no processo bash (processo pai). No processo filho, o espaço no diretório é novo e não posso acessar o espaço no diretório do processo pai a partir daí. Portanto, nada poderia ser feito, exceto invocado uma nova janela do bash a partir daqui. No futuro, tentarei implementar um novo recurso de guia se as pessoas estiverem interessadas nisso. Mas acredito que tenho enfrentado muitas críticas por fazer isso. Portanto, as pessoas podem não estar interessadas. Acabei de fazer por minha diversão.

O código RAW é compartilhado aqui,

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

}

Estou usando o terminal gnome aqui. Obviamente, para outras distribuições, o código será alterado.

Pilot6
fonte
1
Se você pudesse mover para um diretório dentro de um script de shell, poderá originar o script para realizar o que deseja. O define um alias para encurtar o comando.
precisa saber é o seguinte
19

Qualquer entidade (na maioria) dos sistemas de arquivos no Linux possui um identificador exclusivo chamado an inode. Observe que um arquivo pode ter mais de um nome ( hardlink ), mas os diretórios têm apenas um link em todos os sistemas de arquivos que eu conheço. Observe que o conceito de inode é local para o sistema de arquivos, de modo que em dois dispositivos diferentes (partição ou qualquer outra coisa) a exclusividade não é garantida.

Você pode ver o inode do seu diretório com ls -ldi:

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

Portanto, você sabe que seu diretório possui o inode 20873234. Agora você pode alternar para ele com o comando:

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

(Observe que 2> /dev/nullé para fechar as mensagens de erro sobre diretórios ilegíveis ao longo do caminho.)

Este comando varrerá todo o diretório inicial, portanto, seja paciente. 1 1

Mas e o uso cde a conclusão da TAB do seu shell?


1. Este deve ser o mais 2 coisa ineficiente que eu já postou ... uma ode à entropia. O motivo é que a “chave primária” sob a qual o acesso a um arquivo ou diretório é otimizado, rápido e direto é - adivinhem? - o caminho:/dir/dir/file_or_dir. Além disso, para conceder acesso a um determinado diretório, o sistema precisa verificar todas as permissões no caminho ... então, novamente, acessar por inode significa verificar recursivamente o sistema de arquivos.

2. Bem, você pode piorar as coisas digitalizando a partir de/. 3

3. Mas não funcionará, porque os inodes são únicos apenas em um sistema de arquivos (por montagem).

Rmano
fonte
Obrigado @Romano. Na verdade, eu estava pensando sobre o problema. Não sei se o problema se tornaria uma solução tão ineficiente. Mas pense na solução. Você pode escrever facilmente um programa CA e colocá-lo em / bin e tentar executá-lo com o único número de inode. Vou postar o código se for capaz de escrever esse pensamento.
Maruf
1
e também acho que preciso saber. Eu entendo a primeira parte deste comando. "$ (encontre ~ -inum 20873234 ******)". mas eu não sei por que você está escrevendo isso, "2> / dev / null". Você pode esclarecer mais uma vez.
Maruf
4
@ Maruf, não funcionará, em termos de eficiência. A "chave primária" em que o acesso a um arquivo ou diretório é otimizado, rápido e direto é, adivinhem, o caminho ... /dir/dir/file_or_dir. Seu programa C também precisará verificar o sistema de arquivos e findfoi otimizado nos últimos 40 anos ... ainda --- por quê? Se você precisar de um atalho, use a="/my/really/strange and long/dir path name/"e então cd "$a". Não pode vencê-lo. Ou use links simbólicos.
Rmano 8/08/15
1
Um bom +1. Eu estava prestes a escrever algo parecido, mas estava com preguiça, pois a tarefa não tem sentido algum. @Rmano
Pilot6
3
@Rmano Eu acrescentaria que, em geral, mesmo em um único sistema de arquivos, pode haver vários arquivos com o mesmo inode, ou seja, hardlinks. Como estamos falando de diretórios aqui, é verdade que cada diretório possui um inode exclusivo (os diretórios não podem ser vinculados por hardware). Além disso, acho que a razão pela qual não é possível acessar diretamente um arquivo via inode é que isso ignoraria qualquer diretório transversal, necessário para determinar se um usuário tem permissão para acessar o recurso correspondente. (Portanto, se um diretório pode ser acessado pelo seu inode, então o kernel teria que determinar o seu caminho de qualquer maneira.)
Malte Skoruppa
8

Você pode fazer Tabgirar as pastas disponíveis em vez de listá-las. Edite o arquivo ~/.inputrce adicione

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

Se você desejar para todos os usuários, edite /etc/inputrc.

Pressione Ctrl+ xe Ctrl+ rpara torná-lo eficaz.

Agora use cdTabpara navegar para a sua pasta sem escrever o nome. cdShift+ Tabgirará na outra direção.

Vale lembrar que cd -o levará para a última pasta visitada.

Katu
fonte
Esta é uma boa resposta. Você pode exibir uma vez e depois girar?
daltonfury42
1
Você pode atribuir isso a outro atalho. Eu uso o Eclipse e estou acostumado a pressionar Ctrl + espaço para a conclusão automática e, em vez disso, uso "\ C-": menu-complete, deixando a guia como está.
Katu
5

Você pode usar curingas de shell.

Por exemplo, eu posso fazer

cd a?b?c?d

ou

cd a\*b\*c\*d

E ele expandirá os curingas para o nome real e mudará para esse diretório. Supondo que esse seja o único diretório que corresponda.

Se você possui ambos , a b c de a1b2c3d, então cd a?b?c?d, expandirá para um cd a1b2c3d a b c dou cd a b c d a1b2c3d(a ordem real dependerá do kernel, do sistema de arquivos ...) e o bash silenciosamente o moverá para o primeiro caminho.

Por outro lado, muitas vezes você não tem pastas com nomes semelhantes, portanto, algo como a*dé suficiente para expandir isso sem precisar digitar todos os caracteres intermediários. Isso é especialmente útil quando você não é capaz de digitá-lo (por exemplo, os nomes estão em um script diferente ou mesmo em uma codificação diferente), e você precisaria codificar octalmente o nome do arquivo.

Anjo
fonte
3

Você pode encontrar este diretório em um gerenciador de arquivos, como o nautilus, basta arrastar e soltar no terminal.

Se você digitar o cdterminal anteriormente , receberá o comando.

Pilot6
fonte
Na verdade, estou tentando fazer tudo, desde o terminal. :). Portanto, não há necessidade de pensar no nautilus. Eu acho que deve haver um procedimento para acessar o arquivo. Como o Linux sempre salve um identificador exclusivo para um arquivo específico. Mas eu não sei como fazer isso ou isso pode realmente ser feito.
Maruf
Não está claro o que você pergunta. Não é possível mudar para um diretório que não está digitando seu nome de alguma maneira.
precisa saber é o seguinte
Veja a declaração. Eu atualizei.
Maruf
Ou, se este for o problema de um único arquivo, você poderá adicionar um alias.
precisa saber é o seguinte
1

Não tenho certeza se é exatamente isso que você está pedindo, mas zshtem alguns truques para acessar um diretório por outros meios além de digitar o nome estrito do diretório; por um lado, você pode digitar uma parte do nome e ela será expandida para o nome completo do diretório, o que permite coisas muito úteis, por exemplo:

insira a descrição da imagem aqui

Bater TAB...

insira a descrição da imagem aqui

kos
fonte
1

A maneira mais simples é clicar duas vezes no nome do diretório (supondo que esteja visível na tela), digite cd seguido de espaço e clique no botão de roda do mouse e ele copiará e colará o nome do diretório que você destacou. Pressionar a tecla Enter mudará para o diretório necessário.

Eu uso esse procedimento o tempo todo e não se limita apenas aos nomes de diretório. Pode ser usado para qualquer comando usando a linha de comando.

Boa sorte.

Allen
fonte
Isso não vai escapar caracteres especiais
SCz
1

Se for apenas um ou alguns diretórios, por que não ter pseudônimos no bashrc ou em qualquer arquivo init? Por exemplo:

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

Então, sempre que você quiser entrar, basta digitar abc

Hopping Bunny
fonte
0

Você pode escrever um programa para criar uma tabela de hash para todos os diretórios do sistema operacional. Seria basicamente um programa de achatamento de árvores.

Mas então você poderia fazer algo parecido hash-cd 32okjv02e faria a pesquisa de tabela de hash para o 32okjv02mapeamento de diretório to. e pule para o seu diretório. E seria muito rápido assim que você indexasse todos os seus diretórios.

Você teria que usar o mkdir para chamar esse programa a cada novo diretório e talvez escrever um comando de verificação / atualização da tabela de hash que pudesse agendar a cada minuto e no logon.

mutant_city
fonte