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


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 yo uso ls Acabo de ver un signo de interrogación (probablemente debido a la ubicación)

% 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 mv y al usar la tabulación completa me muestra:

% mv
^C/  bin/

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


128
2018-01-21 15:55


origen


Es una pena que dsw no lo hizo en POSIX. - Mark Plotnick
@MarkPlotnick: muy mal la original  dsw no lo hizo en POSIX. - Matteo Italia
No creo que lo nombraras ctrl + C, lo nombraste por el carácter ascii que se asigna a ese atajo de teclado, es decir, ETX (ascii 3) probablemente. La fuente de la consola no tiene ningún glifo para ese carácter, por lo que utiliza un glifo de sustitución genérico "?". - jiggunjer
emacs -nw -f dired Da un navegador de directorio. <kbd> D </kbd> borra el archivo debajo del cursor después de la confirmación. - Thorbjørn Ravn Andersen
@MatteoItalia Es demasiado malo controlar los caracteres en los nombres de archivo y otros idiota  Las ideas se convirtieron en POSIX ... - pipe


Respuestas:


^V (ctrl+v) funciona como un tipo de secuencia de escape para la siguiente pulsación de tecla, insertando el valor asociado en lugar de realizar cualquier acción que normalmente se asociaría.

Haciendo uso de esto, ^V^C (ctrl+v, ctrl+do) Debería trabajar para ingresar su nombre de archivo difícil en el terminal.


189
2018-01-21 16:23



Esta fue probablemente la forma en que OP hizo su error tipográfico en primer lugar. V y C están uno al lado del otro en el teclado. - Stig Hemmer
O intentaban usar el portapapeles de Windows en el terminal bsd. - Joel Coel
Los hábitos de @JoelCoel nunca mueren! - Mafii
Curiosamente, ^V^C hace no trabajar en el editor de líneas Zsh; la citar-insertar widget (busca 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 suministrar un carácter de control en un argumento de shell. - Miles
@StigHemmer: lo que también puede suceder es que presione Ctrl-C en medio de un comando, luego se olvide de esto y luego copie y pegue el comando. - Mehrdad


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 pongas -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
$ 

Felicidades, acabas de borrar todos tus archivos Con find, el orden de los argumentos importa!


89
2018-01-22 03:42



¿Por qué no poner -delete antes de -inum? ¿Es esto solo una precaución en caso de que presione la tecla Entrar prematuramente o el orden de los argumentos realmente afecta el resultado? - detuur
@detuur: el orden afecta el resultado. Ver editar - bishop
No pongas -delete en el comando, punto, hasta que haya ejecutado el comando sin -delete Para comprobar que está encontrando lo que quieres. - Kaz
@Kaz no ayudará mucho con la adición de -delete en el centro del comando - RiaD
@Kaz usando -print en lugar de -delete hace una muy buena prueba - Mark Ransom


Otra opción es usar rm -ri ./*; rm le preguntará antes de eliminar cualquier archivo y directorio, así que solo tiene que responder y al archivo "malo", y n a todos los demás.

En realidad, en su caso, incluso puede reducir el número de respuestas necesarias haciendo rm -ri ./?, ya que su archivo "malo" es de un solo carácter.


31
2018-01-21 20:13



select f in ?; do rm -i "$f"; break; done tiene todos los beneficios de -i, sin la agonía de tener que responder no a los indeseables principales o responder erróneamente a uno que desea conservar. - bishop
En el caso del OP es un directorio, no un archivo. rmdir ?/ eliminará todos los directorios de un solo carácter vacíos y se quejará de que los otros no están vacíos. - Peter Cordes
@bishop: whoa, ni siquiera sabía eso select existía, bastante limpio! - Matteo Italia
@PeterCordes: wops, no me di cuenta de que estábamos hablando de directorios; yo añadí -r (y ./ - Siempre es fácil de olvidar) a mis ejemplos, como desafortunadamente rmdir no soporta el -i bandera. Aun así, supongo que en este caso, la mejor manera de hacerlo sería una combinación de obispos y su comentario. - Matteo Italia
@MatteoItalia select solo existe en algunos shells, por lo que es probable que no se haya encontrado con ellos: los scripts y las soluciones que deben ser portátiles lo evitan, por lo que es menos probable que lo veamos "en la naturaleza". - mtraceur


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

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

Otra opción sería mirar un volcado hexadecimal de la salida de ls, utilizando por ejemplo hexdump.

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

rmdir "$(printf '\x03')"

(Las comillas dobles solo son necesarias si el carácter que intenta imprimir está en su IFS variable, como \x20 o \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.)


23
2018-01-21 18:51



también cat -v (más man ascii) Puede ayudar para la primera parte. - Matteo Italia
... o usas os.rmdir('\x03') directamente desde el shell de Python. - moooeeeep


A menudo, en este tipo de situaciones es fácil llegar a un patrón comodín que coincide con el archivo correspondiente.

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

Solo verifica que realmente coincida con lo que quieres:

ls -ld ?

Y luego quitar el directorio:

rmdir ?

También puedes combinar esto con completar la pestaña. Puede escribir

rmdir ?

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

rmdir ^C/

y luego puedes pulsar enter y hace lo que quieras.


15
2018-01-21 21:02





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

Lo hice de vez en cuando cuando los nombres de los archivos tenían caracteres extraños debido a la codificación.


11
2018-01-21 20:29



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


Otra forma más: usar stat para obtener una representación escapada del nombre del directorio:

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

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

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

O, si estás usando bash, puedes evitar printf:

$ rmdir -v $'\003'
rmdir: removing directory, ‘\003’

7
2018-01-22 10:25



Por cierto si el shell es bash, $'\x03' es más sencillo 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. P.ej. ¿Y si el archivo fuera nombrado? '\111' (en stat salida)? ¿Aún lo eliminarías usando $'\x49'? Mejor usar la misma secuencia que stat Te di: en el caso del OP, rmdir $'\003'. - Ruslan


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 necesitas tener el ajustes necesarios en tu concha para que funcione.


6
2018-01-22 08:31



^ C es realmente temprano en la secuencia de pestañas, así que +1 para ti. - joshudson


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


5
2018-01-21 16:31



¿Realmente te parece más fácil que la respuesta aceptada? - chicks
@chicks: En realidad no es una mala respuesta. He visto que ^ V ^ C no funciona, por lo que alguien podría quedarse atascado. - joshudson
No es incorrecto en sí mismo, pero parece mucho trabajo adicional en comparación con las soluciones más directas. Tal vez estoy echado a perder por Linux, pero ^v Me ha funcionado consistentemente durante años. - chicks
@chicks ^V se necesita un conocimiento específico mientras se mueven los archivos y la eliminación del directorio principal se puede derivar de lo básico. - Kondybas
Ctrl + V es peligrosamente ambiguo dependiendo de su entorno de trabajo exacto ... algunos emuladores de terminal podrían interpretarlo como un pegado. Si su búfer de pegado contiene el nombre de algo que no desea eliminar, y una nueva línea, podría estar viendo un problema. - rackandboneman


Si es el único directorio vacío (o no le importa eliminar otros directorios vacíos), utilizar rmdir */. Recibirá mensajes de error de rmdir sobre no poder eliminar directorios no vacíos, pero eso está bien. ÑU rmdir apoya --ignore-fail-on-non-empty, o podrías 2>/dev/null.

El que se arrastra / hace que glob solo coincida con los nombres de directorio.

Puede verificar con anticipación qué directorios vacíos existen debajo del actual usando
find -maxdepth 1 -type d -empty -ls. (Y puedes cambiar el -ls a -delete si tu quieres).

Podrías usar una expresión glob más específica como rmdir [^A-Za-z0-9._]/ para coincidir con 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 han señalado otros, puede limitarlo a nombres de un solo carácter con un globo de ?: rmdir ?/

rmdir no tiene un -i opción el camino rm lo hace, presumiblemente porque los directorios vacíos usualmente no son valiosos y solo pueden ser recreados.


1
2018-01-22 05:39



Usted querría saber qué directorios desea recrear, y rmdir te puedo decir si pasas -v Opción para ello (al menos en GNU). - Ruslan
@Ruslan: No, si tuviera otros directorios obsoletos que ya no le importaban, y eliminarlos sería una ventaja. Podrías buscar directorios vacíos con find -maxdepth 1 -type d -empty -ls - Peter Cordes


Antes de hacer algo arriesgado, intente esto primero:

rmdir -- ^C

En general, es un delimitador que indica el comando que no seguirán las opciones, pero también permitirá que los caracteres extraños no se interpreten como otra cosa.

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

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

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

Pero en mi csh shell no necesito nada de eso, simplemente rmdir ^C ya funciona para mi


0
2018-01-22 20:12



En csh escribiendo rmdir  seguido de <ctrl> C funciona? ¡¿De Verdad?! Espero que se comporte de manera diferente, es decir, abortando el rmdir comando y regresando a la línea de comandos. - Mausy5043
De hecho lo hará. Vea la respuesta aceptada acerca de cómo ingresar un carácter ^ C en la línea de comando. - Ale