Pertanyaan FreeBSD: Directory bernama ^ C (really!) - cara menghapus?


Saya salah ketik:

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

Sekarang saya memiliki file yang disebut ^ C (ctrl + C) !! Ketika saya menggunakan ls Saya hanya melihat tanda tanya (mungkin karena lokal?)

% 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

dan

% ls -i
3611537 ?   3611534 bin

Saya ingin menghapus file ini. saya coba mv dan saat menggunakan tab-completion, ini menunjukkan:

% mv
^C/  bin/

Jelas saya tidak bisa mengetik ^ C: - / Bagaimana cara menghapus file ini?


128
2018-01-21 15:55




Itu terlalu buruk dsw tidak berhasil masuk ke POSIX. - Mark Plotnick
@MarkPlotnick: terlalu buruk itu asli  dsw tidak berhasil masuk ke POSIX. - Matteo Italia
Saya tidak berpikir Anda menamakannya ctrl + C, Anda menamakannya setelah karakter ascii yang dipetakan ke pintasan keyboard itu, yaitu ETX (ascii 3) mungkin. Font konsol Anda tidak memiliki glyph untuk karakter itu, sehingga menggunakan glyph substitusi umum "?". - jiggunjer
emacs -nw -f dired memberikan navigator direktori. <kbd> D </ kbd> menghapus file di bawah kursor setelah konfirmasi. - Thorbjørn Ravn Andersen
@MatteoItalia Ini karakter kontrol terlalu buruk dalam nama file dan lainnya bodoh  ide membuatnya menjadi POSIX ... - pipe


Jawaban:


^V (ctrl+v) berfungsi sebagai semacam urutan pelolosan untuk penekanan tombol berikutnya, memasukkan nilai yang terkait alih-alih mengambil tindakan apa pun yang biasanya diasosiasikan.

Memanfaatkan ini, ^V^C (ctrl+v, ctrl+c) harus bekerja untuk memasukkan nama file yang sulit di terminal.


189
2018-01-21 16:23



Ini mungkin bagaimana OP membuat kesalahan ketik mereka di tempat pertama. V dan C tepat di sebelah satu sama lain di keyboard. - Stig Hemmer
Atau mereka mencoba menggunakan clipboard Windows pada terminal bsd. - Joel Coel
Kebiasaan @JoelCoel tidak pernah mati! - Mafii
Menariknya, ^V^C tidak tidak bekerja di editor baris Zsh; itu kutipan-insert widget (cari halaman untuk ^V) secara eksplisit tidak memasukkan karakter interupsi. Jawaban Jakob (menggunakan printf) mungkin merupakan cara yang lebih portabel dalam memasok karakter kontrol dalam argumen shell. - Miles
@StigHemmer: Apa yang juga bisa terjadi adalah Anda menekan Ctrl-C di tengah-tengah perintah, lalu lupakan ini dan salin-tempelkan perintah nanti. - Mehrdad


Anda juga dapat menghapus file dengan inode:

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

Apapun yang Anda lakukan, demi Tuhan, jangan dimasukkan -delete sebelum -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
$ 

Selamat, Anda baru saja musnah semua file Anda. Dengan find, Urutan argumen penting!


89
2018-01-22 03:42



Kenapa tidak dimasukkan -delete sebelum -inum? Apakah ini hanya tindakan pencegahan jika Anda menekan enter sebelum waktunya atau apakah urutan argumen benar-benar memengaruhi hasil? - detuur
@detuur: pesanan memengaruhi hasil. Lihat edit. - bishop
Jangan dimasukkan -delete ke dalam perintah, titik, hingga Anda menjalankan perintah tanpa -deleteuntuk memeriksa apakah itu menemukan apa yang Anda inginkan. - Kaz
@Kaz tidak akan banyak membantu dengan menambahkan -Hapus di pusat komando - RiaD
@Kaz menggunakan -print dari pada -delete membuat tes yang sangat bagus. - Mark Ransom


Pilihan lainnya adalah menggunakan rm -ri ./*; rm akan menanyakan Anda sebelum menghapus file dan direktori apa pun, jadi Anda hanya perlu membalas y ke file "buruk", dan n untuk yang lainnya.

Sebenarnya, dalam kasus Anda, Anda bahkan dapat mengurangi jumlah balasan yang dibutuhkan dengan melakukan rm -ri ./?, karena file "buruk" Anda hanya satu karakter.


31
2018-01-21 20:13



select f in ?; do rm -i "$f"; break; done memiliki semua manfaat -i, tanpa penderitaan harus menjawab no untuk mengarahkan orang yang tidak diinginkan atau secara salah menjawab ya ke salah satu yang ingin Anda simpan. - bishop
Dalam kasus OP itu adalah direktori, bukan file. rmdir ?/ akan menghapus semua direktori karakter tunggal kosong, dan mengeluh tentang yang lain tidak kosong. - Peter Cordes
@bishop: whoa, saya bahkan tidak tahu itu select ada, cukup rapi! - Matteo Italia
@PeterCordes: wops, saya tidak memperhatikan bahwa kami berbicara tentang direktori; saya tambahkan -r (dan ./ - Selalu mudah untuk dilupakan) pada contoh saya, sayangnya rmdir tidak mendukung -i bendera. Namun, saya kira dalam hal ini cara terbaik untuk pergi adalah kombinasi dari uskup dan komentar Anda. - Matteo Italia
@MatteoItalia select hanya ada di beberapa cangkang, yang mungkin mengapa Anda tidak mencarinya - skrip dan solusi yang dimaksudkan untuk menghindarinya secara portabel, jadi kita cenderung tidak melihatnya "di alam liar". - mtraceur


Salah satu pilihan adalah mencari nama file dengan sesuatu selain ls. Jika Anda tahu itu diproduksi oleh kata demi kata Ctrl+C, Anda dapat menemukan karakter ASCII yang dihasilkan menggunakan tabel karakter kontrol, atau dengan antarmuka yang lebih ramah seperti yang disediakan oleh Python:

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

Pilihan lain akan melihat hex dump output ls, menggunakan misalnya hexdump.

Kemudian Anda dapat menghapus file dengan (misalnya) perintah bash ini:

rmdir "$(printf '\x03')"

(Kutipan ganda hanya diperlukan jika karakter yang Anda coba cetak ada di Anda IFS variabel, seperti \x20 atau \x0A, tapi itu kebiasaan yang baik untuk mengutip pergantian perintah kecuali Anda tahu Anda ingin shell untuk melakukan pembagian bidang, dll.)


23
2018-01-21 18:51



Juga cat -v (plus man ascii) dapat membantu untuk bagian pertama. - Matteo Italia
... atau Anda gunakan os.rmdir('\x03') langsung dari shell Python. - moooeeeep


Seringkali dalam situasi semacam ini mudah untuk muncul pola wildcard yang cocok dengan file yang relevan.

Dalam kasus Anda, ini akan menjadi sederhana ? (cocok dengan semua nama file dengan tepat satu karakter).

Cukup periksa bahwa itu benar-benar cocok dengan yang Anda inginkan:

ls -ld ?

Dan kemudian hapus direktori:

rmdir ?

Anda juga bisa menggabungkan ini dengan penyelesaian tab. Anda bisa mengetik

rmdir ?

dan tekan tab, dan mis. di bash itu akan digantikan oleh

rmdir ^C/

dan Anda dapat menekan enter dan melakukan apa yang Anda inginkan.


15
2018-01-21 21:02





Anda dapat menggunakan Midnight Commander (mc) untuk menghapus file - cukup pilih dengan tombol naik / turun dan tekan F8.

Saya melakukan itu kadang-kadang ketika nama file memiliki karakter aneh karena encoding.


11
2018-01-21 20:29



Atau hanya tentang file manager lainnya. - Stig Hemmer
@StigHemmer tentu saja, beberapa lebih baik dari yang lain untuk menampilkan nama file tertentu. Mungkin jawabannya bisa menjelaskan mengapa MC adalah pilihan yang optimal dibandingkan dengan beberapa orang lain terpilih. Saya tidak tahu, karena saya tidak pernah menggunakannya. - can-ned_food


Namun cara lain: gunakan stat untuk mendapatkan representasi yang lolos dari nama direktori:

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

Sekarang Anda tahu representasi dari nama file, sehingga Anda dapat menghapus file dengan menggunakan nama printf:

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

Atau, jika Anda menggunakan bash, Anda dapat menghindari printf:

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

7
2018-01-22 10:25



BTW jika shell itu bash, $'\x03' lebih sederhana daripada memanggil printf. Hal yang sama untuk FreeBSD sh yang diperluas melalui POSIX shell dengan beberapa fitur yang enak. - Netch
@Perhatikan poin bagus tentang bash $'...', tapi saya akan menghindari konversi tidak berguna dari oktal ke heksadesimal secara umum. Misalnya. bagaimana jika file itu diberi nama '\111' (di stat keluaran)? Apakah Anda masih menghapusnya menggunakan $'\x49'? Lebih baik gunakan urutan yang sama dengan stat memberi Anda: dalam kasus OP, rmdir $'\003'. - Ruslan


Solusi yang berhasil untuk saya adalah:

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

untuk menelusuri file yang tersedia sampai saya menemukan file yang ingin saya hapus.

Tetapi Anda harus memiliki pengaturan yang diperlukan di shell Anda untuk itu untuk bekerja.


6
2018-01-22 08:31



^ C benar-benar di awal urutan tab jadi +1 untuk Anda. - joshudson


Cara termudah adalah memindahkan semuanya ke direktori sementara dan kemudian rm -r DIRNAME.


5
2018-01-21 16:31



Apakah ini benar-benar lebih mudah bagi Anda daripada jawaban yang diterima? - chicks
@chicks: Sebenarnya bukan jawaban yang buruk. Saya telah melihat ^ V ^ C tidak berfungsi sehingga seseorang mungkin terjebak. - joshudson
Itu tidak salah, tetapi sepertinya banyak kerja ekstra dibandingkan dengan solusi yang lebih langsung. Mungkin saya dimanjakan oleh Linux, tapi ^v telah bekerja secara konsisten selama berabad-abad. - chicks
@chicks ^V membutuhkan pengetahuan khusus saat memindahkan file di sekitar dan penghapusan direktori induk dapat diturunkan dari dasar-dasar. - Kondybas
Ctrl + V adalah ambigu yang berbahaya tergantung pada lingkungan kerja Anda yang sebenarnya ... beberapa emulator terminal dapat menafsirkannya sebagai pasta. Jika buffer pasta Anda berisi nama sesuatu yang tidak ingin Anda hapus - dan baris baru, Anda bisa melihat masalah. - rackandboneman


Jika itu satu-satunya direktori kosong (atau Anda tidak peduli tentang menghapus direktori kosong lainnya), menggunakan rmdir */. Anda akan mendapatkan pesan kesalahan dari rmdir tentang tidak dapat menghapus direktori yang tidak kosong, tapi itu tidak masalah. GNU rmdir mendukung --ignore-fail-on-non-empty, atau kamu bisa 2>/dev/null.

Trailing / membuat glob hanya cocok dengan nama direktori.

Anda dapat memeriksa terlebih dahulu direktori kosong apa yang ada di bawah yang ada saat ini
find -maxdepth 1 -type d -empty -ls. (Dan Anda dapat mengubah -ls untuk -delete jika kamu mau).

Anda bisa menggunakan ekspresi glob yang lebih spesifik seperti rmdir [^A-Za-z0-9._]/ untuk mencocokkan direktori yang dimulai dengan nama file non-alfanumerik atau garis bawah. Saya juga termasuk ., tetapi ekspresi glob tidak cocok . biasanya sih.


Seperti yang telah ditunjukkan oleh orang lain, Anda dapat membatasinya menjadi nama-nama karakter tunggal dengan gumpalan ?: rmdir ?/

rmdir tidak memiliki -i pilihan jalan rm tidak, mungkin karena direktori kosong biasanya tidak berharga dan hanya bisa diciptakan kembali.


1
2018-01-22 05:39



Anda ingin mengetahui direktori mana yang ingin Anda buat ulang, dan rmdir dapat memberi tahu Anda jika Anda lulus -v pilihan untuk itu (setidaknya di GNU). - Ruslan
@Ruslan: Tidak jika Anda memiliki direktori basi lain yang tidak lagi Anda pedulikan, dan menghapusnya akan menjadi bonus. Anda bisa mencari direktori kosong dengan find -maxdepth 1 -type d -empty -ls - Peter Cordes