FreeBSD: Répertoire appelé ^ C (vraiment!) - comment supprimer?

127

J'ai fait une faute de frappe:

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

Maintenant, j'ai un fichier qui s'appelle ^ C (Ctrl + C) !! Lorsque je l'utilise, lsje ne vois qu'un point d'interrogation (probablement en raison des paramètres régionaux?)

% 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

et

% ls -i
3611537 ?   3611534 bin

Je veux supprimer ce fichier. J'essaie mvet lorsque j'utilise l' onglet de complétion, il me montre:

% mv
^C/  bin/

Évidemment, je ne peux pas taper ^ C: - / Comment puis-je supprimer ce fichier?

Mausy5043
la source
11
C'est dommage que dsw n'ait pas réussi à entrer dans POSIX.
Mark Plotnick
12
@ MarkPlotnick: dommage que l' original dsw n'ait pas été intégré à POSIX.
Matteo Italia
4
Je ne pense pas que vous l’ayez nommée ctrl + C, vous l’avez nommée après le caractère ascii associé à ce raccourci clavier, c’est-à-dire ETX (ascii 3) probablement. La police de votre console n'a pas de glyphe pour ce caractère, elle utilise donc un glyphe de substitution générique "?".
Jiggunjer
5
emacs -nw -f direddonne un navigateur de répertoire. <kbd> D </ kbd> supprime le fichier sous le curseur après confirmation.
Thorbjørn Ravn Andersen
9
@MatteoItalia Il est trop mauvais que les caractères de contrôle dans les noms de fichiers et d'autres idées idiotes aient été intégrés à POSIX ...
pipe

Réponses:

188

^V( ctrl+ v) fonctionne comme une sorte de séquence d'échappement pour la prochaine pression sur une touche, insérant la valeur associée au lieu de prendre les mesures qui seraient normalement associées.

Faisant usage de cela, ^V^C( ctrl+ v, ctrl+ c) doit travailler pour saisir votre nom difficile dans le terminal.

Håkan Lindqvist
la source
41
C'est probablement ainsi que OP a créé sa faute de frappe. V et C sont côte à côte sur le clavier.
Stig Hemmer
14
Ou ils essayaient d'utiliser le presse-papiers de Windows sur le terminal BSD.
Joel Coel
2
@JoelCoel habitudes ne meurent jamais!
Mafii
1
Fait intéressant, ^V^Cne fonctionne pas dans l'éditeur de ligne Zsh; le widget quoted-insert (recherche dans la page ^V) explicitement n'insère pas de caractères d'interruption. La réponse de Jakob (utilisant printf) peut constituer un moyen plus portable de fournir un caractère de contrôle dans un argument de shell.
Miles
@StigHemmer: Ce qui peut aussi arriver, c'est d'appuyer sur Ctrl-C au milieu d'une commande, de l'oublier et de copier-coller la commande plus tard.
Mehrdad
89

Vous pouvez également supprimer le fichier par inode:

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

Quoi que vous fassiez, pour l'amour de Dieu, ne mettez pas -deleteavant -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
$ 

Félicitations, vous venez d'effacer tous vos fichiers. Avec find, l' ordre des arguments compte !

évêque
la source
2
Pourquoi ne pas mettre -deleteavant -inum? S'agit-il d'une précaution au cas où vous appuyez sur entrée prématurément ou l'ordre des arguments affecte-t-il réellement le résultat?
mardi
10
@detuur: l'ordre affecte le résultat. Voir éditer.
évêque
37
Ne mettez pas -deletedans la commande, point final, jusqu'à ce que vous ayez exécuté la commande sans -deletevérifier qu'elle trouve ce que vous voulez.
Kaz
2
@Kaz ne m'aidera pas beaucoup avec l'ajout de -delete au centre du commandement
RiaD
9
@Kaz utiliser -printau lieu de -deletefait un très bon test.
Mark Ransom
32

Une autre option est d'utiliser rm -ri ./*; rmvous demandera avant de supprimer un fichier ou un répertoire, il vous suffira donc de répondre yau "mauvais" fichier et nà tous les autres.

En fait, dans votre cas, vous pouvez même réduire le nombre de réponses nécessaires rm -ri ./?, car votre "mauvais" fichier ne contient qu'un seul caractère.

Matteo Italia
la source
8
select f in ?; do rm -i "$f"; break; donea tous les avantages de -i, sans l'agonie d'avoir à répondre noà la conduite des indésirables ou répondre par erreur à une question que vous souhaitez conserver.
Evêque
6
Dans le cas du PO, c'est un répertoire, pas un fichier. rmdir ?/supprime tous les répertoires vides à caractère unique et se plaint du fait que les autres ne sont pas vides.
Peter Cordes
2
@bishop: whoa, je ne savais même pas que ça selectexistait, plutôt chouette!
Matteo Italia
@PeterCordes: wops, je n'ai pas remarqué qu'on parlait de répertoires; J'ai ajouté -r(et ./- il est toujours facile d'oublier) à mes exemples, car malheureusement, rmdiril ne supporte pas le -idrapeau. Néanmoins, je suppose que dans ce cas, la meilleure solution consiste à combiner l'évêque et votre commentaire.
Matteo Italia
1
@MatteoItalia selectn'existe que dans certains coquillages, ce qui explique probablement pourquoi vous ne l'avez pas rencontré: les scripts et les solutions conçus pour être portables l'évitent, nous avons donc moins de chances de le voir "à l'état sauvage".
mtraceur
23

Une option consiste à rechercher le nom du fichier avec autre chose que ls. Si vous savez qu'il a été produit par un verbatim Ctrl+ C, vous pouvez trouver le caractère ASCII généré à l'aide d'une table de caractères de contrôle ou d'une interface plus conviviale comme celle fournie par Python:

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

Une autre option serait de regarder un vidage hexadécimal de la sortie de ls, en utilisant par exemple hexdump.

Ensuite, vous pouvez supprimer le fichier avec (par exemple) cette commande bash:

rmdir "$(printf '\x03')"

(Les guillemets ne sont nécessaires que si le caractère que vous essayez d'imprimer se trouve dans votre IFSvariable, telle que \x20ou \x0A, mais c'est une bonne habitude de citer des substitutions de commandes à moins que vous ne souhaitiez que le shell effectue la division du champ, etc.)

Jakob
la source
2
Aussi cat -v(plus man ascii) peut aider pour la première partie.
Matteo Italia
13
... ou vous utilisez os.rmdir('\x03')directement à partir du shell Python.
moooeeeep
15

Souvent, dans ce type de situation, il est facile de créer un modèle générique correspondant au fichier en question.

Dans votre cas, ce serait simplement ?(faire correspondre tous les noms de fichiers avec exactement un caractère).

Il suffit de vérifier que cela correspond vraiment à ce que vous voulez:

ls -ld ?

Et puis supprimez le répertoire:

rmdir ?

Vous pouvez également combiner ceci avec la complétion par tabulation . Vous pouvez taper

rmdir ?

et appuyez sur l'onglet, et par exemple dans bash il sera remplacé par

rmdir ^C/

et vous pouvez ensuite appuyer sur entrée et il fait ce que vous voulez.

Jukka Suomela
la source
11

Vous pouvez utiliser Midnight Commander (mc) pour supprimer le fichier - il suffit de sélectionner avec les boutons haut / bas et d'appuyer sur F8.

Je le faisais de temps en temps lorsque les noms de fichiers avaient des caractères étranges dus à l'encodage.

filo
la source
4
Ou à peu près tout autre gestionnaire de fichiers.
Stig Hemmer
@ StigHemmer bien sûr, certains font mieux que d'autres pour afficher certains noms de fichiers. La réponse pourrait probablement expliquer pourquoi MC est un choix optimal par rapport à quelques autres. Je ne saurais pas, car je ne l'ai jamais utilisé.
can-ned_food
7

Encore une autre façon: utilisez statpour obtenir une représentation d'échappement du nom du répertoire:

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

Vous connaissez maintenant une représentation du nom du fichier. Vous pouvez donc supprimer le fichier par son nom en utilisant printf:

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

Ou, si vous utilisez bash, vous pouvez éviter printf:

$ rmdir -v $'\003'
rmdir: removing directory, ‘\003’
Ruslan
la source
BTW si le shell est bash, $'\x03'est plus simple que d’appeler printf. La même chose pour FreeBSD sh qui est étendu sur le shell POSIX avec quelques fonctionnalités savoureuses.
Netch
@Netch est un bon point à propos de bash $'...', mais j'éviterais une conversion inutile d'octal en hexadécimal en général. Par exemple, que faire si le fichier était nommé '\111'(en statsortie)? Voulez-vous toujours l'enlever en utilisant $'\x49'? Mieux utiliser la même séquence que statvous a donné: dans le cas de l'OP, rmdir $'\003'.
Ruslan
6

Une solution qui a fonctionné pour moi est la suivante:

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

parcourir les fichiers disponibles jusqu'à ce que je trouve celui que je veux supprimer.

Mais pour que cela fonctionne, vous devez disposer des paramètres nécessaires dans votre shell.

Joeytwiddle
la source
^ C est vraiment au début de la séquence de tabulation, donc +1 pour vous.
Joshudson
5

Le moyen le plus simple est de tout déplacer dans le répertoire temporaire, puis rm -r DIRNAME.

Kondybas
la source
7
Cela vous semble-t-il plus facile que la réponse acceptée?
poussins
2
@chicks: Ce n'est en fait pas une si mauvaise réponse. J'ai vu ^ V ^ C ne fonctionnait pas pour que quelqu'un puisse rester bloqué.
joshudson
Ce n'est pas une erreur en soi, mais cela semble être beaucoup de travail supplémentaire par rapport aux solutions plus directes. Peut-être que je suis gâté par Linux, mais que cela ^vfait toujours très longtemps que je travaille.
poussins
6
@chicks a ^Vbesoin de connaissances spécifiques pour pouvoir déplacer des fichiers et la suppression du répertoire parent peut être déduite des bases.
Kondybas
5
Ctrl + V est dangereusement ambigu selon votre environnement de travail… Certains émulateurs de terminaux pourraient l’interpréter comme une pâte. Si votre tampon de collage contient le nom de quelque chose que vous ne voulez pas supprimer - et une nouvelle ligne, vous pourriez être en train de regarder un problème.
rackandboneman
1

S'il s'agit du seul répertoire vide (ou si vous ne vous souciez pas de supprimer d'autres répertoires vides), utilisezrmdir */ . Vous obtiendrez des messages d'erreur rmdirindiquant que vous ne pourrez pas supprimer les répertoires non vides, mais c'est bien. GNU rmdirprend en charge --ignore-fail-on-non-empty, ou vous pourriez 2>/dev/null.

La fin /fait en sorte que le glob ne corresponde qu'aux noms de répertoire.

Vous pouvez vérifier à l'avance quels répertoires vides existent sous le répertoire actuel en utilisant
find -maxdepth 1 -type d -empty -ls. (Et vous pouvez changer le -lsen -deletesi vous voulez).

Vous pouvez utiliser une expression globale plus spécifique, par exemple rmdir [^A-Za-z0-9._]/pour faire correspondre les répertoires commençant par un nom de fichier non alphanumérique ou un trait de soulignement. J'ai aussi inclus ., mais les expressions globales ne correspondent pas .normalement de toute façon.


Comme d'autres l'ont fait remarquer, vous pouvez le limiter à des noms à caractère unique avec un glob de ?: rmdir ?/

rmdirn'a probablement pas la même -ioption rm, probablement parce que les répertoires vides ne sont généralement pas utiles et peuvent simplement être recréés.

Peter Cordes
la source
1
Vous voudriez savoir quels répertoires vous voulez recréer, et rmdirvous dire si vous lui passez l' -voption (au moins dans GNU).
Ruslan
@Ruslan: Pas si vous aviez d'autres répertoires obsolètes que vous n'aimiez plus, et les supprimer serait un bonus. Vous pouvez chercher des répertoires vides avecfind -maxdepth 1 -type d -empty -ls
Peter Cordes
-1

Avant de faire quelque chose de risqué, essayez ceci en premier:

rmdir -- ^C

En général - est un délimiteur indiquant à la commande que aucune commande ne suivra, mais cela permettra également aux caractères étranges de ne pas être interprétés comme autre chose.

Un autre exemple d'utilisation est whois -r -- "-r OBJECT-RIPE"

(-r est un raccourci pour mûr, mais dans le whois mûr est aussi un paramètre)

Si cela ne fonctionne pas au premier essai, alors peut-être essayer rmdir -- "^C"

Mais sur mon shell csh, je n’en ai pas besoin, tout simplement rmdir ^Cdéjà pour moi.

Leo Vandew.
la source
1
En csh, taper rmdir suivi de <ctrl> C fonctionne? Vraiment?! Je m'attendrais à ce qu'il se comporte différemment, à savoir l'abandon de la rmdircommande et le renvoi à la ligne de commande.
Mausy5043
Ça va en effet. Voir la réponse acceptée sur la manière de saisir un caractère ^ C sur la ligne de commande.
Ale