FreeBSD: Directorio llamado ^ C (¡en serio!) - ¿Cómo eliminarlo?

127

Hice un error tipográfico:

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

¡Ahora tengo un archivo que se llama ^ C (ctrl + C)! Cuando lo uso ls, solo veo un signo de interrogación (¿probablemente debido a la configuración regional?)

% 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

y

% ls -i
3611537 ?   3611534 bin

Quiero eliminar este archivo Lo intento mvy cuando uso la finalización de pestaña me muestra:

% mv
^C/  bin/

Obviamente no puedo escribir un ^ C: - / ¿Cómo elimino este archivo?

Mausy5043
fuente
11
Es una pena que dsw no haya llegado a POSIX.
Mark Plotnick
12
@ MarkPlotnick: lástima que el original dsw no haya llegado a POSIX.
Matteo Italia
44
No creo que lo haya llamado ctrl + C, lo nombró por el carácter ascii que está asignado a ese atajo de teclado, es decir, ETX (ascii 3) probablemente. La fuente de su consola no tiene glifo para ese carácter, por lo que utiliza un glifo de sustitución genérico "?".
jiggunjer
55
emacs -nw -f diredda un navegador de directorio. <kbd> D </kbd> elimina el archivo debajo del cursor después de la confirmación.
Thorbjørn Ravn Andersen
99
@MatteoItalia Es una lástima que los personajes de control en los nombres de archivo y otras ideas idiotas hayan llegado a POSIX ...
canalización

Respuestas:

188

^V( ctrl+ v) funciona como una especie de secuencia de escape para la siguiente pulsación de tecla, insertando el valor asociado en lugar de tomar cualquier acción que normalmente estaría asociada.

Hacer uso de esto, ^V^C( ctrl+ v, ctrl+ c) debería funcionar para ingresar su nombre de archivo difícil en la terminal.

Håkan Lindqvist
fuente
41
Probablemente así fue como OP hizo su error tipográfico en primer lugar. V y C están uno al lado del otro en el teclado.
Stig Hemmer
14
O estaban tratando de usar el portapapeles de Windows en el terminal bsd.
Joel Coel
2
¡Los hábitos de @JoelCoel nunca mueren!
Mafii
1
Curiosamente, ^V^Cno no trabajar en el editor de línea Zsh; el widget de inserción entre comillas (buscar en la página ^V) explícitamente no inserta caracteres de interrupción. La respuesta de Jakob (usando printf) puede ser una forma más portátil de proporcionar un carácter de control en un argumento de shell.
Millas el
@StigHemmer: Lo que también puede suceder es presionar Ctrl-C en el medio de un comando, luego olvidarse de esto y copiar y pegar el comando más tarde.
Mehrdad
89

También puede eliminar el archivo por inode:

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

Hagas lo que hagas, por el amor de Dios, no lo pongas -deleteantes -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
$ 

Felicitaciones, acabas de borrar todos tus archivos. Con find, el orden importa argumento !

obispo
fuente
2
¿Por qué no poner -deleteantes -inum? ¿Es esto solo una precaución en caso de que presione enter prematuramente o el orden de los argumentos realmente afecta el resultado?
detuur
10
@detuur: el orden afecta el resultado. Ver editar.
obispo
37
No ponga -deleteen el comando, punto, hasta que haya ejecutado el comando sin -deleteverificar que está encontrando lo que desea.
Kaz
2
@Kaz no ayudará mucho al agregar -delete en el centro de comando
RiaD
99
@Kaz usando en -printlugar de -deletehace una muy buena prueba.
Mark Ransom el
32

Otra opción es usar rm -ri ./*; rmle preguntará antes de eliminar cualquier archivo y directorio, por lo que solo debe responder yal archivo "incorrecto" y na todos los demás.

En realidad, en su caso, incluso puede reducir la cantidad de respuestas necesarias rm -ri ./?, ya que su archivo "malo" tiene solo un carácter.

Matteo Italia
fuente
8
select f in ?; do rm -i "$f"; break; donetiene todos los beneficios de -i, sin la agonía de tener que responder noa los principales indeseables o responder erróneamente sí a uno que desea conservar.
obispo
66
En el caso del OP, es un directorio, no un archivo. rmdir ?/eliminará todos los directorios vacíos de un solo carácter y se quejará de que los demás no están vacíos.
Peter Cordes
2
@bishop: whoa, ni siquiera sabía que selectexistía, ¡bastante bien!
Matteo Italia
@PeterCordes: wops, no me di cuenta de que estábamos hablando de directorios; Agregué -r(y ./siempre es fácil de olvidar) a mis ejemplos, ya que desafortunadamente rmdirno admite la -ibandera. Aún así, supongo que en este caso la mejor manera de hacerlo sería una combinación de obispos y su comentario.
Matteo Italia
1
@MatteoItalia selectsolo existe en algunos shells, por lo que probablemente no te hayas encontrado con él: los scripts y las soluciones destinadas a ser portátiles lo evitan, por lo que es menos probable que lo veamos "en la naturaleza".
mtraceur
23

Una opción es buscar el nombre del archivo con algo diferente a ls. Si sabe que fue producido por un literal Ctrl+ C, puede encontrar el carácter ASCII producido usando una tabla de caracteres de control o con una interfaz más amigable como la que proporciona Python:

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

Otra opción sería mirar un volcado hexadecimal de la salida de ls, usando eg hexdump.

Luego puede eliminar el archivo con (por ejemplo) este comando bash:

rmdir "$(printf '\x03')"

(Las comillas dobles solo son necesarias si el carácter que está intentando imprimir está en su IFSvariable, como \x20o \x0A, pero es un buen hábito citar sustituciones de comandos a menos que sepa que desea que el shell realice la división de campos, etc.)

Jakob
fuente
2
Además cat -v(más man ascii) puede ayudar en la primera parte.
Matteo Italia
13
... o lo usas os.rmdir('\x03')directamente desde el shell de Python.
moooeeeep
15

A menudo, en este tipo de situaciones, es fácil encontrar un patrón comodín que coincida con el archivo relevante.

En su caso, esto sería simplemente ?(hacer coincidir todos los nombres de archivo con exactamente un carácter).

Solo verifique que realmente coincida con lo que desea:

ls -ld ?

Y luego elimine el directorio:

rmdir ?

También puede combinar esto con la finalización de pestañas . Puedes escribir

rmdir ?

y presione tab y, por ejemplo, en bash será reemplazado por

rmdir ^C/

y luego puedes presionar enter y hace lo que quieras.

Jukka Suomela
fuente
11

Puede usar Midnight Commander (mc) para eliminar el archivo; simplemente seleccione con los botones arriba / abajo y presione F8.

Hice eso ocasionalmente cuando los nombres de los archivos tenían caracteres extraños debido a la codificación.

filo
fuente
44
O casi cualquier otro administrador de archivos.
Stig Hemmer
@StigHemmer, por supuesto, algunos lo hacen mejor que otros para mostrar ciertos nombres de archivo. Probablemente la respuesta podría explicar por qué MC es una opción óptima en comparación con algunos otros seleccionados. No lo sabría, ya que nunca lo he usado.
can-ned_food
7

Otra forma más: utilícela statpara obtener una representación escapada del nombre del directorio:

$ stat *|grep File:
  File: ‘\003’

Ahora conoce una representación del nombre del archivo, por lo que puede eliminar el archivo por nombre usando printf:

$ rmdir -v "$(printf '\003')"
rmdir: removing directory, ‘\003’

O, si está usando bash, puede evitar printf:

$ rmdir -v $'\003'
rmdir: removing directory, ‘\003’
Ruslan
fuente
Por cierto, si el shell es bash, $'\x03'es más simple que llamar a printf. Lo mismo para FreeBSD sh que se extiende sobre POSIX shell con algunas características sabrosas.
Netch
@Netch buen punto sobre bash $'...', pero evitaría la conversión inútil de octal a hexadecimal en general. Por ejemplo, ¿qué pasaría si se nombrara el archivo '\111'(en la statsalida)? ¿Aún lo eliminarías usando $'\x49'? Un mejor uso de la misma secuencia que statle dio: en el caso de la OP, rmdir $'\003'.
Ruslan
6

Una solución que me ha funcionado es:

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

para recorrer los archivos disponibles hasta que encuentre el que quiero eliminar.

Pero necesita tener la configuración necesaria en su shell para que eso funcione.

joeytwiddle
fuente
^ C es realmente temprano en la secuencia de pestañas, por lo que +1 para usted.
joshudson el
5

La forma más fácil es mover todo al directorio temporal y luego rm -r DIRNAME.

Kondybas
fuente
77
¿Esto realmente te parece más fácil que la respuesta aceptada?
chicas
2
@chicks: en realidad no es una respuesta tan mala. He visto que ^ V ^ C no funciona, por lo que alguien podría quedarse atascado.
joshudson
No está mal per se, pero parece mucho trabajo extra en comparación con las soluciones más directas. Tal vez estoy mimado por Linux, pero me ^vha funcionado constantemente durante años.
chicas
66
@chicks ^Vnecesita un conocimiento específico al mover archivos y la eliminación del directorio principal se puede derivar de lo básico.
Kondybas
55
Ctrl + V es peligrosamente ambiguo dependiendo de su entorno de trabajo exacto ... algunos emuladores de terminal podrían interpretarlo como una pasta. Si su búfer de pegado contiene el nombre de algo que no desea eliminar, y una nueva línea, podría estar buscando un problema.
rackandboneman
1

Si es el único directorio vacío (o si no le importa eliminar otros directorios vacíos), usermdir */ . Recibirá mensajes de error rmdiracerca de no poder eliminar directorios no vacíos, pero está bien. GNU rmdiradmite --ignore-fail-on-non-empty, o podrías 2>/dev/null.

El seguimiento /hace que el globo solo coincida con los nombres de directorio.

Puede verificar con anticipación qué directorios vacíos existen bajo el actual usando
find -maxdepth 1 -type d -empty -ls. (Y puede cambiar -lsa -deletesi lo desea).

Puede usar una expresión glob más específica, como rmdir [^A-Za-z0-9._]/hacer coincidir los directorios que comienzan con un nombre de archivo no alfanumérico o de subrayado. También incluí ., pero las expresiones glob no coinciden .normalmente de todos modos.


Como otros han señalado, puede limitarlo a nombres de un solo carácter con un globo de ?: rmdir ?/

rmdirno tiene una -iopción como lo rmhace, presumiblemente porque los directorios vacíos generalmente no son valiosos y solo se pueden volver a crear.

Peter Cordes
fuente
1
Desea saber qué directorios desea recrear y rmdirpuede decirle si le pasa la -vopción (al menos en GNU).
Ruslan
@Ruslan: No si tuvieras otros directorios obsoletos que ya no te importaban, y eliminarlos sería una ventaja. Puede buscar directorios vacíos confind -maxdepth 1 -type d -empty -ls
Peter Cordes
-1

Antes de hacer algo arriesgado, intente esto primero:

rmdir -- ^C

En general, es un delimitador que le dice al comando que no seguirán las opciones, pero también permitirá que los caracteres extraños no se interpreten como algo más.

Otro ejemplo de uso es whois -r -- "-r OBJECT-RIPE"

(-r es un atajo para maduro, pero en el maduro también es un parámetro)

Si no funciona en el primer intento, entonces tal vez intente rmdir -- "^C"

Pero en mi shell csh no necesito nada de eso, simplemente rmdir ^Cya funciona para mí.

Leo Vandew
fuente
1
En csh escribiendo rmdir seguido de <ctrl> C funciona? ¡¿De Verdad?! Esperaría que se comportara de manera diferente, es decir, abortar el rmdircomando y regresarlo a la línea de comando.
Mausy5043
De hecho lo hará. Vea la respuesta aceptada sobre cómo ingresar un carácter ^ C en la línea de comando.
Ale