FreeBSD: Thư mục có tên ^ C (thực sự!) - làm thế nào để loại bỏ?


127

Tôi đã đánh máy:

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

Bây giờ tôi có một tệp có tên ^ C (ctrl + C) !! Khi tôi sử dụng lstôi chỉ thấy một dấu hỏi (có thể là do miền địa phương?)

% 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

% ls -i
3611537 ?   3611534 bin

Tôi muốn xóa tập tin này. Tôi thử mvvà khi sử dụng hoàn thành tab, nó hiển thị cho tôi:

% mv
^C/  bin/

Rõ ràng tôi không thể gõ một ^ C: - / Làm cách nào để xóa tệp này?


11
Thật tệ khi dsw không biến nó thành POSIX.
Đánh dấu Plotnick

12
@MarkPlotnick: quá tệ khi bản gốc dsw không được đưa vào POSIX.
Matteo Italia

4
Tôi không nghĩ bạn đã đặt tên cho nó là ctrl + C, bạn đặt tên nó theo ký tự ascii được ánh xạ tới phím tắt đó, có lẽ là ETX (ascii 3). Phông chữ điều khiển của bạn không có glyph cho ký tự đó, vì vậy nó sử dụng glyph thay thế chung "?".
jiggunjer

5
emacs -nw -f diredđưa ra một thư mục điều hướng. <kbd> D </ kbd> xóa tệp dưới con trỏ sau khi xác nhận.
Thorbjørn Ravn Andersen

9
@MatteoItalia Các nhân vật điều khiển quá tệ trong tên tệp và các ý tưởng ngu ngốc khác đã biến nó thành POSIX ...
ống

Câu trả lời:


188

^V( ctrl+ v) hoạt động như một loại chuỗi thoát cho lần nhấn phím tiếp theo, chèn giá trị được liên kết thay vì thực hiện bất kỳ hành động nào thường được liên kết.

Sử dụng điều này, ^V^C( ctrl+ v, ctrl+ c) nên hoạt động để nhập tên tệp khó của bạn vào thiết bị đầu cuối.


41
Đây có lẽ là cách OP tạo ra lỗi đánh máy của họ ở nơi đầu tiên. V và C nằm ngay cạnh nhau trên bàn phím.
Stig Hemmer

14
Hoặc họ đang cố gắng sử dụng bảng tạm Windows trên thiết bị đầu cuối bsd.
Joel Coel

2
Thói quen @JoelCoel không bao giờ chết!
Mafii

1
Điều thú vị là ^V^Ckhông không làm việc trong trình soạn thảo dòng Zsh; các quoted-insert phụ tùng (tìm kiếm các trang cho ^V) một cách rõ ràng không chèn ký tự ngắt. Câu trả lời của Jakob (sử dụng printf) có thể là một cách dễ dàng hơn để cung cấp một ký tự điều khiển trong một đối số shell.
Miles

@StigHemmer: Điều gì cũng có thể xảy ra là bạn nhấn Ctrl-C ở giữa một lệnh, sau đó quên điều này và sao chép-dán lệnh sau.
Mehrdad

89

Bạn cũng có thể xóa tệp bằng inode:

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

Dù bạn làm gì, vì Chúa, đừng đặt -deletetrước -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
$ 

Xin chúc mừng, bạn vừa xóa sạch tất cả các tập tin của bạn. Với find, vấn đề tranh luận !


2
Tại sao không đặt -deletetrước -inum? Đây chỉ là một biện pháp phòng ngừa trong trường hợp bạn nhấn enter sớm hoặc thứ tự của các đối số thực sự ảnh hưởng đến kết quả?
mất

10
@detuur: thứ tự ảnh hưởng đến kết quả. Xem chỉnh sửa.
giám mục

37
Đừng đưa -deletevào lệnh, khoảng thời gian, cho đến khi bạn chạy lệnh mà không -deletekiểm tra xem nó có tìm thấy thứ bạn muốn không.
Kaz

2
@Kaz sẽ không giúp được gì nhiều với việc thêm -delete vào trung tâm chỉ huy
Rịa

9
@Kaz sử dụng -printthay vì -deletelàm một bài kiểm tra rất tốt.
Đánh dấu tiền chuộc

32

Một lựa chọn khác là sử dụng rm -ri ./*; rmsẽ hỏi bạn trước khi xóa bất kỳ tệp và thư mục nào, vì vậy bạn chỉ cần trả lời ytệp "xấu" và ncho tất cả những người khác.

Trên thực tế, trong trường hợp của bạn, bạn thậm chí có thể cắt giảm số lượng trả lời cần thiết bằng cách thực hiện rm -ri ./?, vì tệp "xấu" của bạn chỉ dài một ký tự.


8
select f in ?; do rm -i "$f"; break; donecó tất cả những lợi ích của -i, mà không có sự đau đớn khi phải trả lời nođể dẫn đến những điều không mong muốn hoặc trả lời sai có cho một người bạn muốn giữ.
giám mục

6
Trong trường hợp của OP, đó là một thư mục, không phải tệp. rmdir ?/sẽ xóa tất cả các thư mục ký tự trống và phàn nàn về các thư mục khác không trống.
Peter Cordes

2
@bishop: whoa, tôi thậm chí còn không biết rằng nó selecttồn tại, khá gọn gàng!
Matteo Italia

@PeterCordes: wops, tôi đã không nhận thấy rằng chúng ta đang nói về các thư mục; Tôi đã thêm -r(và ./- luôn dễ quên) vào các ví dụ của mình, vì không may là rmdirkhông hỗ trợ -icờ. Tuy nhiên, tôi cho rằng trong trường hợp này cách tốt nhất để đi là sự kết hợp giữa giám mục và nhận xét của bạn.
Matteo Italia

1
@MatteoItalia selectchỉ tồn tại trong một số shell, đó có thể là lý do tại sao bạn không chạy vào nó - các tập lệnh và giải pháp có nghĩa là có thể di động tránh được nó, vì vậy chúng tôi ít thấy nó "trong tự nhiên".
mtraceur

23

Một tùy chọn là tìm kiếm tên tệp với cái gì đó khác ls. Nếu bạn biết nó được tạo bởi một nguyên văn Ctrl+ C, bạn có thể tìm thấy ký tự ASCII được tạo bằng bảng ký tự điều khiển hoặc với giao diện thân thiện hơn như giao diện do Python cung cấp:

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

Một lựa chọn khác là xem xét một kết xuất hex của đầu ra ls, sử dụng ví dụ hexdump.

Sau đó, bạn có thể xóa tệp bằng (ví dụ) lệnh bash này:

rmdir "$(printf '\x03')"

(Các dấu ngoặc kép chỉ cần thiết nếu nhân vật bạn đang cố gắng để in là ở bạn IFSbiến, chẳng hạn như \x20hay \x0A, nhưng đó là một thói quen tốt để báo giá thay thế lệnh trừ khi bạn biết bạn muốn vỏ để thực hiện tách lĩnh vực, vv)


2
Ngoài ra cat -v(cộng man ascii) có thể giúp cho phần đầu tiên.
Matteo Italia

13
... Hoặc bạn sử dụng os.rmdir('\x03')trực tiếp từ trình bao Python.
moooeeeep

15

Thông thường trong loại tình huống này, thật dễ dàng để đưa ra một mẫu ký tự đại diện phù hợp với tệp có liên quan.

Trong trường hợp của bạn, điều này sẽ đơn giản ?(khớp tất cả các tên tệp với chính xác một ký tự).

Chỉ cần kiểm tra xem nó thực sự phù hợp với những gì bạn muốn:

ls -ld ?

Và sau đó xóa thư mục:

rmdir ?

Bạn cũng có thể kết hợp điều này với hoàn thành tab . Bạn có thể gõ

rmdir ?

và nhấn tab, và ví dụ trong bash, nó sẽ được thay thế bằng

rmdir ^C/

và sau đó bạn có thể nhấn enter và nó làm những gì bạn muốn.


11

Bạn có thể sử dụng Midnight Commander (mc) để xóa tệp - chỉ cần chọn bằng các nút lên / xuống và nhấn F8.

Tôi đã làm điều đó đôi khi khi tên tập tin có ký tự lạ do mã hóa.


4
Hoặc chỉ về bất kỳ trình quản lý tập tin khác.
Stig Hemmer

@StigHemmer tất nhiên, một số làm tốt hơn những người khác để hiển thị tên tệp nhất định. Có lẽ câu trả lời có thể giải thích tại sao MC là một lựa chọn tối ưu so với một số ít người khác chọn. Tôi sẽ không biết, vì tôi chưa bao giờ sử dụng nó.
can-ned_food

7

Một cách khác: sử dụng statđể có được một đại diện thoát của tên thư mục:

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

Bây giờ bạn đã biết cách thể hiện tên tệp, vì vậy bạn có thể xóa tệp theo tên bằng cách sử dụng printf:

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

Hoặc, nếu bạn đang sử dụng bash, bạn có thể tránh printf:

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

BTW nếu shell là bash, $'\x03'đơn giản hơn so với gọi printf. Điều tương tự đối với FreeBSD sh được mở rộng trên vỏ POSIX với một số tính năng ngon.
Lấy

@ Tìm điểm tốt về bash's $'...', nhưng tôi sẽ tránh chuyển đổi vô dụng từ bát phân sang thập lục phân nói chung. Ví dụ: nếu tập tin được đặt tên '\111'( statđầu ra) thì sao? Bạn vẫn sẽ loại bỏ nó bằng cách sử dụng $'\x49'? Tốt hơn nên sử dụng trình tự tương tự như statđã cho bạn: trong trường hợp của OP , rmdir $'\003'.
Ruslan

6

Một giải pháp hiệu quả với tôi là:

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

để duyệt qua các tệp có sẵn cho đến khi tôi tìm thấy tệp tôi muốn xóa.

Nhưng bạn cần phải có các cài đặt cần thiết trong vỏ để hoạt động.


^ C thực sự sớm trong chuỗi tab vì vậy +1 cho bạn.
joshudson

5

Cách dễ nhất là di chuyển mọi thứ vào thư mục tạm thời và sau đó rm -r DIRNAME.


7
Điều này thực sự có vẻ dễ dàng với bạn hơn câu trả lời được chấp nhận?
gà con

2
@chicks: Thật ra đó không phải là một câu trả lời tồi. Tôi đã thấy ^ V ^ C không hoạt động nên ai đó có thể bị kẹt.
joshudson

Điều đó không sai mỗi lần, nhưng có vẻ như rất nhiều công việc làm thêm so với các giải pháp trực tiếp hơn. Có thể tôi hư hỏng bởi Linux, nhưng ^vđã làm việc liên tục với tôi từ lâu.
gà con

6
@chicks ^Vcần một kiến ​​thức cụ thể trong khi di chuyển các tệp xung quanh và xóa thư mục mẹ có thể được lấy từ những điều cơ bản.
Kondybas

5
Ctrl + V mơ hồ một cách nguy hiểm tùy thuộc vào môi trường làm việc chính xác của bạn ... một số trình giả lập thiết bị đầu cuối có thể hiểu nó là một dán. Nếu bộ đệm dán của bạn chứa tên của một cái gì đó bạn không muốn xóa - và một dòng mới, bạn có thể đang xem xét một vấn đề.
rackandboneman

1

Nếu đó là thư mục trống duy nhất (hoặc bạn không quan tâm đến việc xóa các thư mục trống khác), hãy sử dụngrmdir */ . Bạn sẽ nhận được thông báo lỗi rmdirvề việc không thể xóa các thư mục không trống, nhưng không sao. GNU rmdirhỗ trợ --ignore-fail-on-non-empty, hoặc bạn có thể 2>/dev/null.

Các trailing /làm cho toàn cầu chỉ khớp tên thư mục.

Bạn có thể kiểm tra trước những thư mục trống tồn tại trong thư mục hiện tại bằng cách sử dụng
find -maxdepth 1 -type d -empty -ls. (Và bạn có thể thay đổi -lsthành -deletenếu bạn muốn).

Bạn có thể sử dụng một biểu thức toàn cầu cụ thể hơn rmdir [^A-Za-z0-9._]/để khớp với các thư mục bắt đầu bằng tên tệp không phải là chữ và số. Tôi cũng bao gồm ., nhưng .dù sao biểu thức toàn cầu không khớp .


Như những người khác đã chỉ ra, bạn có thể giới hạn nó ở các tên một ký tự với toàn cầu ?: rmdir ?/

rmdirkhông có -itùy chọn nào rm, có lẽ vì các thư mục trống thường không có giá trị và chỉ có thể được tạo lại.


1
Bạn muốn biết thư mục nào bạn muốn tạo lại và rmdircó thể cho bạn biết nếu bạn chuyển -vtùy chọn cho nó (ít nhất là trong GNU).
Ruslan

@Ruslan: Không phải nếu bạn có các thư mục cũ khác mà bạn không còn quan tâm nữa, và loại bỏ chúng sẽ là một phần thưởng. Bạn có thể tìm các thư mục trống vớifind -maxdepth 1 -type d -empty -ls
Peter Cordes

-1

Trước khi làm bất cứ điều gì rủi ro, hãy thử điều này trước:

rmdir -- ^C

Nói chung - là một dấu phân cách cho biết lệnh không có lệnh nào sẽ tuân theo, nhưng nó cũng sẽ cho phép các ký tự lạ không được hiểu là một thứ khác.

Một ví dụ sử dụng khác là whois -r -- "-r OBJECT-RIPE"

(-r là một phím tắt cho chín, nhưng trong whois chín cũng là một tham số)

Nếu lần đầu tiên nó không hoạt động, thì có thể thử rmdir -- "^C"

Nhưng tại vỏ csh của tôi, tôi không cần bất kỳ thứ gì, đơn giản là nó rmdir ^Cđã hoạt động với tôi.


1
Trong gõ csh rmdir theo sau là <ctrl> C hoạt động? Có thật không?! Tôi hy vọng nó sẽ hành xử khác đi, cụ thể là hủy bỏ rmdirlệnh và đưa bạn trở lại dòng lệnh.
Mausy5043

Nó thực sự sẽ. Xem câu trả lời được chấp nhận về cách nhập ký tự ^ C trên dòng lệnh.
Ale
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.