FreeBSD: Katalog o nazwie ^ C (naprawdę!) - jak usunąć?


127

Zrobiłem literówkę:

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

Teraz mam plik o nazwie ^ C (ctrl + C) !! Kiedy używam ls, po prostu widzę znak zapytania (prawdopodobnie z powodu ustawień regionalnych?)

% 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

i

% ls -i
3611537 ?   3611534 bin

Chcę usunąć ten plik. Próbuję, mva przy użyciu uzupełniania tabulatorów pokazuje mi:

% mv
^C/  bin/

Oczywiście nie mogę wpisać ^ C: - / Jak usunąć ten plik?


11
Szkoda, że dsw nie dostało się do POSIX.
Mark Plotnick

12
@MarkPlotnick: szkoda, że oryginał dsw nie przeszedł na POSIX.
Matteo Italia

4
Nie sądzę, że nazwałeś go ctrl + C, nazwałeś go po znaku ascii, który jest odwzorowany na ten skrót klawiaturowy, tj. Prawdopodobnie ETX (ascii 3). Czcionka konsoli nie ma żadnego glifu dla tego znaku, więc używa ogólnego glifu podstawienia „?”.
jiggunjer

5
emacs -nw -f direddaje nawigator katalogów. <kbd> D </kbd> usuwa plik pod kursorem po potwierdzeniu.
Thorbjørn Ravn Andersen

9
@MatteoItalia To zbyt złe znaki kontrolne w nazwach plików i inne idiotyczne pomysły trafiły do POSIX ...
pipe

Odpowiedzi:


188

^V( ctrl+ v) działa jako rodzaj sekwencji ucieczki dla następnego naciśnięcia klawisza, wstawiając powiązaną wartość zamiast wykonywania czynności, które normalnie byłyby powiązane.

Korzystając z tego, ^V^C( ctrl+ v, ctrl+ c) powinien działać, aby wprowadzić trudną nazwę pliku w terminalu.


41
Prawdopodobnie w ten sposób OP zrobiło literówkę. V i C znajdują się obok siebie na klawiaturze.
Stig Hemmer

14
Lub próbowali użyć schowka Windows na terminalu bsd.
Joel Coel

2
@JoelCoel nawyki nigdy nie umierają!
Mafii

1
Co ciekawe, ^V^Cma nie pracować w edytorze linii zsh; quoted-insert widget (przeszukać stronę dla ^V) wyraźnie nie wstawić znaki przerwań. Odpowiedź Jakoba (za pomocą printf) może być bardziej przenośnym sposobem dostarczenia znaku kontrolnego w argumencie powłoki.
Miles

@StigHemmer: Możesz również nacisnąć Ctrl-C w środku polecenia, a następnie zapomnieć o tym i skopiować i wkleić polecenie później.
Mehrdad

89

Możesz także usunąć plik za pomocą i-węzła:

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

Cokolwiek robicie, na miłość boską, nie stawiajcie -deleteprzedtem -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
$ 

Gratulacje, właśnie wyczyściłeś wszystkie swoje pliki. Z find, kolejność argumentów ma znaczenie !


2
Dlaczego nie postawić -deletewcześniej -inum? Czy to tylko środek ostrożności w przypadku przedwczesnego naciśnięcia klawisza Enter lub kolejność argumentów faktycznie wpływa na wynik?
detuur

10
@detuur: kolejność wpływa na wynik. Zobacz edycję.
biskup

37
Nie wpisuj -deletepolecenia, kropka, dopóki nie uruchomisz polecenia bez -deletesprawdzenia, czy znajduje to, czego szukasz.
Kaz

2
@Kaz niewiele pomoże w dodaniu -delete w centrum dowodzenia
RiaD

9
Używanie @Kaz -printzamiast -deleterobi bardzo dobry test.
Mark Ransom,

32

Inną opcją jest użycie rm -ri ./*; rmzapyta cię przed usunięciem dowolnego pliku i katalogu, więc musisz tylko odpowiedzieć yna „zły” plik i nna wszystkie pozostałe.

W rzeczywistości możesz nawet zmniejszyć liczbę potrzebnych odpowiedzi rm -ri ./?, ponieważ „zły” plik ma tylko jeden znak.


8
select f in ?; do rm -i "$f"; break; donema wszystkie zalety -i, bez męki polegającej na tym, że trzeba odpowiadać nona wiodące działania niepożądane lub omyłkowo odpowiadać tak na osobę, którą chcesz zatrzymać.
biskup

6
W przypadku OP jest to katalog, a nie plik. rmdir ?/usunie wszystkie puste katalogi jednoznakowe i narzeka, że ​​inne nie są puste.
Peter Cordes

2
@bishop: whoa, nawet nie wiedziałem, że selectistnieje, całkiem fajnie!
Matteo Italia,

@PeterCordes: wops, nie zauważyłem, że rozmawiamy o katalogach; Dodałem -r(i ./- zawsze łatwo zapomnieć) do moich przykładów, ponieważ niestety rmdirnie obsługuje -iflagi. Przypuszczam jednak, że w tym przypadku najlepszym rozwiązaniem będzie połączenie wypowiedzi biskupa i twojego komentarza.
Matteo Italia,

1
@MatteoItalia selectistnieje tylko w niektórych powłokach, prawdopodobnie dlatego go nie spotkałeś - skrypty i rozwiązania, które mają być przenośne, unikają go, więc mniej prawdopodobne jest, że zobaczymy go „na wolności”.
mtraceur

23

Jedną z opcji jest sprawdzenie nazwy pliku za pomocą czegoś innego niż ls. Jeśli wiesz, że został stworzony przez verbatim Ctrl+ C, możesz znaleźć znak ASCII utworzony przy użyciu tabeli znaków kontrolnych lub z bardziej przyjaznym interfejsem, takim jak ten zapewniany przez Python:

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

Inną opcją byłoby przyjrzenie się zrzutowi szesnastkowemu wyniku ls, używając np hexdump.

Następnie możesz usunąć plik za pomocą (na przykład) tego polecenia bash:

rmdir "$(printf '\x03')"

(Podwójne cudzysłowy są potrzebne tylko wtedy, gdy znak, który próbujesz wydrukować, znajduje się w IFSzmiennej, takiej jak \x20lub \x0A, ale dobrym zwyczajem jest cytowanie podstawień poleceń, chyba że wiesz, że chcesz, aby powłoka wykonywała podział pola itp.)


2
Również cat -v(plus man ascii) może pomóc w pierwszej części.
Matteo Italia

13
... lub używasz os.rmdir('\x03')bezpośrednio z powłoki Python.
moooeeeep

15

Często w tego rodzaju sytuacjach łatwo jest znaleźć wzór wieloznaczny pasujący do odpowiedniego pliku.

W twoim przypadku byłoby to po prostu ?(dopasowanie wszystkich nazw plików z dokładnie jednym znakiem).

Po prostu sprawdź, czy naprawdę pasuje do tego, co chcesz:

ls -ld ?

A następnie usuń katalog:

rmdir ?

Możesz także połączyć to z uzupełnianiem tabulatorów . Możesz pisać

rmdir ?

i naciśnij tab, i np. w bash zostanie zastąpiony przez

rmdir ^C/

a następnie możesz nacisnąć Enter i robi to, co chcesz.


11

Możesz użyć Midnight Commander (mc), aby usunąć plik - po prostu wybierz za pomocą przycisków góra / dół i naciśnij F8.

Robiłem to czasami, gdy nazwy plików miały dziwne znaki z powodu kodowania.


4
Lub prawie jakikolwiek inny menedżer plików.
Stig Hemmer

@StigHemmer, oczywiście, niektórzy radzą sobie lepiej niż inni pod względem wyświetlania niektórych nazw plików. Prawdopodobnie odpowiedź mogłaby wyjaśnić, dlaczego MC jest optymalnym wyborem w porównaniu z kilkoma wybranymi innymi. Nie wiedziałbym, bo nigdy go nie użyłem.
can-ned_food

7

Jeszcze inny sposób: użyj, stataby uzyskać ucieczkową reprezentację nazwy katalogu:

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

Teraz znasz reprezentację nazwy pliku, dzięki czemu możesz usunąć plik według nazwy, używając printf:

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

Lub, jeśli używasz bash, możesz uniknąć printf:

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

BTW, jeśli powłoka jest bash, $'\x03'jest prostsze niż wywołanie printf. To samo dotyczy sh FreeBSD, który jest rozszerzony na powłokę POSIX z kilkoma smakowitymi funkcjami.
Netch

@ Pobierz dobrą rację na temat basha $'...', ale ogólnie unikałbym bezużytecznej konwersji z ósemkowej na szesnastkową. Np. Co jeśli plik zostałby nazwany '\111'( statwyjściowy)? Czy nadal byś go usunął za pomocą $'\x49'? Lepiej wykorzystywać tę samą sekwencję jak statdał ci: w przypadku PO za, rmdir $'\003'.
Ruslan

6

Rozwiązaniem, które zadziałało dla mnie jest:

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

cyklicznie przeglądać dostępne pliki, aż znajdę ten, który chcę usunąć.

Ale aby to działało, musisz mieć niezbędne ustawienia w swojej powłoce.


^ C jest naprawdę wcześnie w sekwencji tabulatorów, więc +1 dla Ciebie.
joshudson

5

Najprostszym sposobem jest przeniesienie wszystkiego do katalogu tymczasowego, a następnie rm -r DIRNAME.


7
Czy to naprawdę wydaje ci się łatwiejsze niż zaakceptowana odpowiedź?
pisklęta

2
@ chicks: Właściwie to nie jest taka zła odpowiedź. Widziałem, że ^ V ^ C nie działa, więc ktoś może utknąć.
joshudson

Nie jest to samo w sobie złe, ale wydaje się, że to dużo dodatkowej pracy w porównaniu do bardziej bezpośrednich rozwiązań. Być może Linux mnie rozpieszcza, ale ^vod wieków działał konsekwentnie.
pisklęta

6
@ pisklęta ^Vpotrzebują konkretnej wiedzy podczas przenoszenia plików, a usunięcie katalogu nadrzędnego można uzyskać z podstaw.
Kondybas

5
Ctrl + V jest niebezpiecznie niejednoznaczny w zależności od konkretnego środowiska pracy ... niektóre emulatory terminali mogą interpretować to jako pastę. Jeśli bufor wklejania zawiera nazwę czegoś, czego nie chcesz usuwać - i nowy wiersz, możesz patrzeć na problem.
rackandboneman

1

Jeśli jest to jedyny pusty katalog (lub nie obchodzi Cię usuwanie innych pustych katalogów), użyjrmdir */ . Otrzymasz komunikaty o błędach z rmdirpowodu niemożności usunięcia niepustych katalogów, ale to w porządku. GNU rmdirobsługuje --ignore-fail-on-non-empty, a ty możesz 2>/dev/null.

Końcowe /powoduje, że glob pasuje tylko do nazw katalogów.

Możesz z góry sprawdzić, które puste katalogi istnieją w bieżącym za pomocą
find -maxdepth 1 -type d -empty -ls. (I można zmienić -ls, aby -delete, jeśli chcesz).

Można użyć bardziej szczegółowego wyrażenia glob, na przykład rmdir [^A-Za-z0-9._]/do dopasowania katalogów rozpoczynających się od niealfanumerycznej lub podkreślonej nazwy pliku. Uwzględniłem również ., ale wyrażenia glob i tak nie pasują .normalnie.


Jak zauważyli inni, możesz ograniczyć je do nazw jednoznakowych za pomocą globu ?: rmdir ?/

rmdirnie ma takiej -iopcji rm, prawdopodobnie dlatego, że puste katalogi zwykle nie są cenne i można je po prostu odtworzyć.


1
Chcesz wiedzieć, które katalogi chcesz odtworzyć, i rmdirmożesz powiedzieć, czy podasz -vopcję (przynajmniej w GNU).
Ruslan

@ Ruslan: Nie, jeśli miałbyś inne przestarzałe katalogi, o które już Ci nie chodziło, a usunięcie ich byłoby bonusem. Możesz szukać pustych katalogów zfind -maxdepth 1 -type d -empty -ls
Peter Cordes

-1

Zanim zrobisz coś ryzykownego, spróbuj najpierw:

rmdir -- ^C

Ogólnie rzecz biorąc - jest separatorem informującym, że polecenie nie będzie wykonywane, ale pozwoli także na interpretowanie dziwnych znaków jako czegoś innego.

Innym przykładem użycia jest whois -r -- "-r OBJECT-RIPE"

(-r jest skrótem dla dojrzałych, ale u dojrzałych whois również parametr)

Jeśli to nie działa przy pierwszej próbie, może spróbuj rmdir -- "^C"

Ale w mojej powłoce csh nie potrzebuję jej, po prostu rmdir ^Cjuż działa dla mnie.


1
W wpisywaniu w csh rmdir następuje <ctrl> C działa? Naprawdę?! Spodziewałbym się, że zachowa się inaczej, a mianowicie przerwie rmdirpolecenie i powróci do linii poleceń.
Mausy5043

Rzeczywiście tak będzie. Zobacz zaakceptowaną odpowiedź na temat wprowadzania znaku ^ C w wierszu polecenia.
Ale
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.