FreeBSD: Diretório chamado ^ C (realmente!) - como remover?

128

Eu cometi um erro de digitação:

$ history
169 9:34    la /usr/local/etc/
170 9:35    sudo mkdir ^C
171 9:36    sudo mkdir /usr/local/etc/dnsmasq.d

Agora eu tenho um arquivo chamado ^ C (ctrl + C) !! Quando eu uso ls eu só vejo um ponto de interrogação (provavelmente devido à localidade?)

% ls -al
total 60
drwxr-xr-x  2 root   wheel    512 Jan 21 09:35 ?        <- this one
drwxr-xr-x  5 admin  wheel    512 Jan 21 16:24 .
drwxr-xr-x  3 root   wheel    512 Jan 20 14:29 ..
-rw-r--r--  1 admin  nobody  1114 Jan 20 19:10 .cshrc
-rw-------  1 admin  wheel   6002 Jan 21 15:27 .history
-rw-r--r--  1 admin  nobody   182 Jan 20 14:29 .login
-rw-r--r--  1 admin  nobody    91 Jan 20 14:29 .login_conf
-rw-------  1 admin  nobody   301 Jan 20 14:29 .mail_aliases
-rw-r--r--  1 admin  nobody   271 Jan 20 19:04 .mailrc
-rw-r--r--  1 admin  nobody   726 Jan 20 19:05 .profile
-rw-------  1 admin  nobody   212 Jan 20 14:29 .rhosts
-rw-r--r--  1 admin  nobody   911 Jan 20 19:06 .shrc
drwx------  2 admin  nobody   512 Jan 20 15:05 .ssh
drwxr-xr-x  2 admin  wheel    512 Jan 20 19:08 bin

e

% ls -i
3611537 ?   3611534 bin

Eu quero remover este arquivo. Eu tento mv e quando uso o preenchimento de tabulação ele me mostra:

% mv
^C/  bin/

Obviamente, não consigo digitar um ^ C: - / Como eu removo este arquivo?

    
por Mausy5043 21.01.2018 / 16:55

11 respostas

189

^V ( ctrl + v ) funciona como um tipo de sequência de escape para o próximo pressionamento de tecla, inserindo o valor associado em vez de executar qualquer ação que possa normalmente estar associado.

Fazendo uso disso, ^V^C ( ctrl + v , ctrl + c ) deve trabalhar para inserir seu nome de arquivo difícil no terminal.

    
por 21.01.2018 / 17:23
89

Você também pode remover o arquivo por inode:

$ ls -i1
290742 foo
293246 ^C
$ find . -inum 293246 -delete

Não importa o que você faça, pelo amor de Deus, não coloque -delete antes de -inum :

$ touch foo bar baz quux
$ find . -name '*u*' -delete
$ ls
bar baz foo
$ find . -delete -name 'b*'
find: './baz': No such file or directory
find: './bar': No such file or directory
$ ls
$ 

Parabéns, você acabou de eliminar todos seus arquivos. Com find , a ordem dos argumentos é importante !

    
por 22.01.2018 / 04:42
32

Outra opção é usar rm -ri ./* ; rm perguntará antes de excluir qualquer arquivo e diretório, então você só precisa responder y ao arquivo "ruim" e n a todos os outros.

Na verdade, no seu caso, você pode até reduzir o número de respostas necessárias fazendo rm -ri ./? , já que seu arquivo "ruim" tem apenas um caractere.

    
por 21.01.2018 / 21:13
23

Uma opção é procurar o nome do arquivo com algo diferente de ls . Se você sabe que foi produzido por um verbatim Ctrl + C , você pode encontrar o caractere ASCII produzido usando um tabela de caracteres de controle , ou com uma interface mais amigável como a fornecida pelo Python:

>>> import os
>>> os.listdir('.')
['\x03', ...]

Outra opção seria examinar um hex dump da saída de ls , usando, por exemplo, hexdump .

Em seguida, você pode excluir o arquivo com (por exemplo) este comando bash:

rmdir "$(printf '\x03')"

(As aspas duplas são necessárias apenas se o caractere que você está tentando imprimir estiver na variável IFS , como \x20 ou \x0A , mas é um bom hábito de citar as substituições de comando, a menos que você conheça quer que o shell execute a divisão de campo, etc.)

    
por 21.01.2018 / 19:51
15

Geralmente, nesse tipo de situação, é fácil criar um padrão curinga que corresponda ao arquivo relevante.

No seu caso, isso seria simplesmente ? (correspondendo todos os nomes de arquivo com exatamente um caractere).

Basta verificar se realmente corresponde ao que você deseja:

ls -ld ?

E, em seguida, remova o diretório:

rmdir ?

Você também pode combinar isso com a conclusão da guia . Você pode digitar

rmdir ?

e pressione tab e, e. no bash será substituído por

rmdir ^C/

e você pode clicar em enter e fazer o que quiser.

    
por 21.01.2018 / 22:02
11

Você pode usar o Midnight Commander (mc) para excluir o arquivo - basta selecionar com os botões para cima / para baixo e pressionar F8.

Eu fiz isso ocasionalmente quando os nomes dos arquivos tinham caracteres estranhos devido à codificação.

    
por 21.01.2018 / 21:29
7

Ainda de outra forma: use stat para obter uma representação de escape do nome do diretório:

$ stat *|grep File:
  File: ‘
$ rmdir -v "$(printf '
$ rmdir -v $'
$ stat *|grep File:
  File: ‘
$ rmdir -v "$(printf '
$ rmdir -v $'%pre%3'
rmdir: removing directory, ‘%pre%3’
3')" rmdir: removing directory, ‘%pre%3’
3’
3' rmdir: removing directory, ‘%pre%3’
3')" rmdir: removing directory, ‘%pre%3’
3’

Agora você conhece uma representação do nome do arquivo para poder remover o arquivo pelo nome usando printf :

%pre%

Ou, se você estiver usando bash, você pode evitar printf :

%pre%     
por 22.01.2018 / 11:25
6

Uma solução que funcionou para mim é:

rm ./[Tab][Tab][Tab]...

para percorrer os arquivos disponíveis até encontrar o que eu quero remover.

Mas você precisa ter o configurações necessárias no seu shell para que isso funcione.

    
por 22.01.2018 / 09:31
5

A maneira mais fácil é mover tudo para o diretório temporário e, em seguida, rm -r DIRNAME .

    
por 21.01.2018 / 17:31
1

Se for o único diretório vazio (ou você não se importa em remover outros diretórios vazios), use rmdir */ . Você receberá mensagens de erro de rmdir sobre não conseguir remover diretórios não vazios, mas tudo bem. O% GNUrmdir suporta --ignore-fail-on-non-empty ou você pode 2>/dev/null .

O trailing / faz com que o glob corresponda apenas aos nomes dos diretórios.

Você pode verificar antecipadamente quais diretórios vazios existem sob o atual usando find -maxdepth 1 -type d -empty -ls . (E você pode mudar o -ls para -delete se quiser).

Você pode usar uma expressão glob mais específica, como rmdir [^A-Za-z0-9._]/ , para corresponder diretórios que começam com um nome de arquivo não alfanumérico ou de sublinhado. Também incluí . , mas as expressões glob não correspondem a . normalmente, de qualquer forma.

Como outros apontaram, você pode limitá-lo a nomes de caractere único com um globo de ? : rmdir ?/

rmdir não tem uma opção -i como ocorre com rm , presumivelmente porque os diretórios vazios geralmente não são valiosos e podem ser recriados.

    
por 22.01.2018 / 06:39
-1

Antes de fazer qualquer coisa arriscada, tente primeiro:

rmdir -- ^C

Em geral - é um delimitador informando o comando que nenhuma opção seguirá, mas também permitirá que caracteres estranhos não sejam interpretados como algo diferente.

Outro exemplo de uso é whois -r -- "-r OBJECT-RIPE"

(- r é um atalho para maduro, mas no maduro whois também é um parâmetro)

Se não funcionar na primeira tentativa, talvez tente rmdir -- "^C"

Mas no meu shell csh eu não preciso de nada, simplesmente rmdir ^C já funciona para mim.

    
por 22.01.2018 / 21:12