FreeBSD: Directory chiamata ^ C (davvero!) - come rimuoverla?


127

Ho fatto un refuso:

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

Ora ho un file che si chiama ^ C (ctrl + C) !! Quando uso lsvedo solo un punto interrogativo (probabilmente a causa della localizzazione?)

% 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

Voglio rimuovere questo file. Provo mve quando si utilizza il completamento con tabulazione mi mostra:

% mv
^C/  bin/

Ovviamente non riesco a digitare un ^ C: - / Come rimuovo questo file?


11
Peccato che dsw non sia riuscito a trasformarlo in POSIX.
Mark Plotnick,

12
@MarkPlotnick: peccato che l' originale dsw non sia arrivato in POSIX.
Matteo Italia,

4
Non credo che tu l'abbia chiamato ctrl + C, l'hai chiamato dopo il carattere ASCII che è mappato a quella scorciatoia da tastiera, cioè probabilmente ETX (ascii 3). Il carattere della tua console non ha glifi per quel personaggio, quindi usa un glifo di sostituzione generico "?".
Jiggunjer,

5
emacs -nw -f diredfornisce un navigatore di directory. <kbd> D </kbd> cancella il file sotto il cursore dopo la conferma.
Thorbjørn Ravn Andersen,

9
@MatteoItalia È troppo male il controllo dei personaggi nei nomi dei file e altre idee idiote trasformate in POSIX ...
pipe

Risposte:


188

^V( ctrl+ v) funziona come una specie di sequenza di escape per la successiva pressione del tasto, inserendo il valore associato invece di intraprendere qualsiasi azione che verrebbe normalmente associata.

Usando questo, ^V^C( ctrl+ v, ctrl+ c) dovrebbe funzionare per inserire il tuo nome di file difficile nel terminale.


41
Questo è stato probabilmente il modo in cui OP ha fatto il suo refuso in primo luogo. V e C sono uno accanto all'altro sulla tastiera.
Stig Hemmer,

14
Oppure stavano cercando di usare gli Appunti di Windows sul terminale bsd.
Joel Coel,

2
Le abitudini di JoelCoel non muoiono mai!
Mafii,

1
È interessante notare ^V^Cche non funziona nell'editor di linea Zsh; il widget di inserimento tra virgolette (cerca nella pagina ^V) esplicitamente non inserisce caratteri di interruzione. La risposta di Jakob (usando printf) potrebbe essere un modo più portatile di fornire un personaggio di controllo in un argomento shell.
Miglia

@StigHemmer: Ciò che può anche accadere è premere Ctrl-C nel mezzo di un comando, quindi dimenticarlo e copiare e incollare il comando in un secondo momento.
Mehrdad,

89

È inoltre possibile rimuovere il file tramite inode:

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

Qualunque cosa tu faccia, per l'amor di Dio, non mettere -deletedavanti -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
$ 

Congratulazioni, hai appena cancellato tutti i tuoi file. Con find, l' ordine degli argomenti conta !


2
Perché non metterlo -deleteprima -inum? È solo una precauzione nel caso in cui si prema invio prematuramente o l'ordine degli argomenti influisce sul risultato?
detuur

10
@detuur: l'ordine influenza il risultato. Vedi modifica.
vescovo

37
Non inserire -deleteil comando, punto, fino a quando non hai eseguito il comando senza -deleteverificare che trovi quello che desideri.
Kaz,

2
@Kaz non aiuterà molto con l'aggiunta di -delete al centro del comando
RiaD

9
L'utilizzo di @Kaz -printinvece di -deleteun ottimo test.
Mark Ransom il

32

Un'altra opzione è usare rm -ri ./*; rmti chiederà prima di eliminare qualsiasi file e directory, quindi devi solo rispondere yal file "non valido" e na tutti gli altri.

In realtà, nel tuo caso puoi anche ridurre il numero di risposte necessarie facendo rm -ri ./?, poiché il tuo file "cattivo" è lungo solo un carattere.


8
select f in ?; do rm -i "$f"; break; doneha tutti i vantaggi di -i, senza l'agonia di dover rispondere noa indesiderabili leader o rispondere erroneamente sì a uno che si desidera mantenere.
vescovo

6
Nel caso dell'OP si tratta di una directory, non di un file. rmdir ?/rimuoverà tutte le directory vuote a carattere singolo e si lamenterà del fatto che le altre non sono vuote.
Peter Cordes,

2
@bishop: whoa, non sapevo nemmeno che selectesistesse, abbastanza pulito!
Matteo Italia,

@PeterCordes: wops, non ho notato che stavamo parlando di directory; Ho aggiunto -r(e ./- è sempre facile dimenticare) ai miei esempi, poiché purtroppo rmdirnon supporta la -ibandiera. Tuttavia, suppongo che in questo caso il modo migliore per andare sarebbe una combinazione di vescovo e il tuo commento.
Matteo Italia,

1
@MatteoItalia selectesiste solo in alcune shell, il che probabilmente è il motivo per cui non ci si è imbattuti: script e soluzioni che dovrebbero essere portatili lo evitano, quindi abbiamo meno probabilità di vederlo "in the wild".
mtraceur,

23

Un'opzione è cercare il nome del file con qualcosa di diverso da ls. Se sai che è stato prodotto da un Ctrl+ verbatim C, puoi trovare il carattere ASCII prodotto usando una tabella di caratteri di controllo o con un'interfaccia più amichevole come quella fornita da Python:

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

Un'altra opzione sarebbe quella di esaminare un dump esadecimale dell'output di ls, usando ad es hexdump.

Quindi è possibile eliminare il file con (ad esempio) questo comando bash:

rmdir "$(printf '\x03')"

(Le doppie virgolette sono necessarie solo se il carattere che stai cercando di stampare è nella tua IFSvariabile, come \x20o \x0A, ma è una buona abitudine citare le sostituzioni di comandi a meno che tu non sappia che vuoi che la shell esegua la divisione dei campi, ecc.)


2
Inoltre cat -v(più man ascii) può aiutare per la prima parte.
Matteo Italia,

13
... o lo usi os.rmdir('\x03')direttamente dalla shell Python.
Moooeeeep

15

Spesso in questo tipo di situazioni è facile elaborare un modello jolly che corrisponda al file pertinente.

Nel tuo caso, questo sarebbe semplicemente ?(abbinando tutti i nomi di file con esattamente un carattere).

Controlla che corrisponda davvero a quello che vuoi:

ls -ld ?

E quindi rimuovere la directory:

rmdir ?

Puoi anche combinare questo con il completamento della scheda . Puoi digitare

rmdir ?

e premi tab, ed es. in bash sarà sostituito da

rmdir ^C/

e puoi quindi premere invio e fa quello che vuoi.


11

È possibile utilizzare Midnight Commander (mc) per eliminare il file: basta selezionare con i pulsanti su / giù e premere F8.

L'ho fatto occasionalmente quando i nomi dei file avevano strani caratteri a causa della codifica.


4
O quasi qualsiasi altro file manager.
Stig Hemmer,

@StigHemmer ovviamente, alcuni fanno meglio di altri per visualizzare determinati nomi di file. Probabilmente la risposta potrebbe spiegare perché MC è una scelta ottimale rispetto ad alcuni altri selezionati. Non lo saprei, non l'ho mai usato.
can-ned_food,

7

Ancora un altro modo: usare statper ottenere una rappresentazione di escape del nome della directory:

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

Ora conosci una rappresentazione del nome del file, quindi puoi rimuovere il file per nome usando printf:

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

Oppure, se stai usando bash, puoi evitare printf:

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

A proposito, se la shell è bash, $'\x03'è più semplice che chiamare printf. Lo stesso per FreeBSD sh che si estende sulla shell POSIX con alcune funzioni interessanti.
Netch

@Prendi un buon punto su bash $'...', ma eviterei inutili conversioni da ottali a esadecimali in generale. Ad esempio, se il file fosse denominato '\111'(in statoutput)? Lo rimuoveresti ancora usando $'\x49'? Meglio usare la stessa sequenza come statti ha dato: nel caso del PO, rmdir $'\003'.
Ruslan,

6

Una soluzione che ha funzionato per me è:

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

per scorrere i file disponibili fino a quando non trovo quello che voglio rimuovere.

Ma hai bisogno di avere le impostazioni necessarie nella tua shell per farlo funzionare.


^ C è molto presto nella sequenza delle schede, quindi +1 per te.
joshudson,

5

Il modo più semplice è spostare tutto nella directory temporanea e quindi rm -r DIRNAME.


7
Ti sembra davvero più facile della risposta accettata?
pulcini,

2
@chicks: In realtà non è una brutta risposta. Ho visto ^ V ^ C non funzionare, quindi qualcuno potrebbe rimanere bloccato.
joshudson,

Di per sé non è sbagliato, ma sembra un sacco di lavoro extra rispetto alle soluzioni più dirette. Forse sono viziato da Linux, ma ^vha funzionato costantemente per anni.
pulcini,

6
@chicks ^Vnecessita di una conoscenza specifica durante lo spostamento dei file e la rimozione della directory principale può essere derivata dalle basi.
Kondybas,

5
Ctrl + V è pericolosamente ambiguo a seconda del tuo esatto ambiente di lavoro ... alcuni emulatori di terminale potrebbero interpretarlo come un incolla. Se il buffer di incollaggio contiene il nome di qualcosa che non si desidera eliminare e una nuova riga, si potrebbe verificare un problema.
rackandboneman,

1

Se è l'unica directory vuota (o non ti interessa rimuovere altre directory vuote), usarmdir */ . Riceverai messaggi di errore dal rmdirnon essere in grado di rimuovere le directory non vuote, ma va bene. GNU rmdirsupporta --ignore-fail-on-non-empty, o potresti 2>/dev/null.

Il trailing /fa sì che il glob corrisponda solo ai nomi delle directory.

Puoi controllare in anticipo quali directory vuote esistono sotto quella corrente usando
find -maxdepth 1 -type d -empty -ls. (E puoi cambiare -lsin -deletese vuoi).

È possibile utilizzare un'espressione glob più specifica, rmdir [^A-Za-z0-9._]/ad esempio per abbinare directory che iniziano con un nome non alfanumerico o di sottolineatura. Ho anche incluso ., ma comunque le espressioni glob non corrispondono .normalmente.


Come altri hanno sottolineato, puoi limitarlo a nomi a carattere singolo con una sfera di ?: rmdir ?/

rmdirnon ha -iun'opzione come quella rm, presumibilmente perché le directory vuote di solito non sono preziose e possono essere semplicemente ricreate.


1
Vorresti sapere quali directory vuoi ricreare e rmdirpoterti dire se gli passi l' -vopzione (almeno in GNU).
Ruslan,

@Ruslan: Non se avessi altre directory obsolete che non ti interessavano più, e rimuoverle sarebbe un bonus. Puoi cercare directory vuote confind -maxdepth 1 -type d -empty -ls
Peter Cordes, il

-1

Prima di fare qualcosa di rischioso, prova questo:

rmdir -- ^C

In generale - è un delimitatore che dice al comando che non seguiranno -o le pozioni, ma consentirà anche che caratteri strani non vengano interpretati come qualcos'altro.

Un altro esempio di utilizzo è whois -r -- "-r OBJECT-RIPE"

(-r è una scorciatoia per maturi, ma anche in whois maturo è un parametro)

Se non funziona al primo tentativo, allora forse prova rmdir -- "^C"

Ma nella mia shell csh non ne ho bisogno, semplicemente rmdir ^Cfunziona già per me.


1
Nella digitazione csh rmdir seguita da <ctrl> C funziona? Veramente?! Mi aspetto che si comporti in modo diverso, in particolare interrompendo il rmdircomando e riportandoti alla riga di comando.
Mausy5043,

Lo farà davvero. Vedi la risposta accettata su come inserire un carattere ^ C nella riga di comando.
Ale
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.