题 FreeBSD:名为^ C的目录(真的!) - 如何删除?


我弄错了:

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

现在我有一个名为^ C(ctrl + C)的文件!! 我用的时候 ls 我只看到一个问号(可能是由于语言环境?)

% 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

我想删除此文件。我试试 mv 当使用制表符完成时,它显示我:

% mv
^C/  bin/

显然我不能输入^ C: - / 如何删除此文件?


128
2018-01-21 15:55




这太糟糕了 DSW 没有进入POSIX。 - Mark Plotnick
@MarkPlotnick:太糟糕了 该 原版的  dsw 没有进入POSIX。 - Matteo Italia
我不认为你将它命名为ctrl + C,你将它命名为映射到该键盘快捷键的ascii字符,即ETX(ascii 3)。您的控制台字体没有该字符的字形,因此它使用通用替换字形“?”。 - jiggunjer
emacs -nw -f dired 给出一个目录导航器。 <kbd> D </ kbd>在确认后删除光标下的文件。 - Thorbjørn Ravn Andersen
@MatteoItalia文件名和其他文件中的控制字符太糟糕了 痴  想法变成了POSIX ...... - pipe


答案:


^V (CTRL+v作为下一次按键的一种转义序列,插入相关值而不是采取通常会关联的任何动作。

利用这个, ^V^C (CTRL+vCTRL+C)应该在终端输入你难以辨认的文件名。


189
2018-01-21 16:23



这可能是OP首先制造他们的拼写错误的原因。键盘上的V和C彼此相邻。 - Stig Hemmer
或者他们试图在bsd终端上使用Windows剪贴板。 - Joel Coel
@JoelCoel的习惯永远不会死! - Mafii
有趣的是, ^V^C 不 不 在Zsh行编辑器中工作;该 带引号的插入 小部件(搜索页面 ^V)明确地不插入中断字符。 Jakob的答案(使用printf)可能是一种在shell参数中提供控制字符的更便携方式。 - Miles
@StigHemmer:在命令中间按Ctrl-C也会发生什么,然后忘记这一点并稍后复制粘贴命令。 - Mehrdad


您也可以通过inode删除该文件:

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

无论你做什么,为了上帝的缘故,不要放 -delete 之前 -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
$ 

恭喜你,你刚刚消失了 所有 你的文件。 find论证顺序很重要


89
2018-01-22 03:42



为什么不放 -delete 之前 -inum?这只是一个预防措施,以防你提前按下输入或参数的顺序是否实际影响结果? - detuur
@detuur:订单影响结果。见编辑。 - bishop
不要放 -delete 进入命令,句点,直到你没有运行命令 -delete 检查它是否找到你想要的东西。 - Kaz
@Kaz对于在命令中心添加-delete没有多大帮助 - RiaD
@Kaz使用 -print 代替 -delete 做了一个很好的测试。 - Mark Ransom


另一种选择是使用 rm -ri ./*; rm 在删除任何文件和目录之前会问你,所以你只需要回复 y 到“坏”文件,和 n 对所有其他人。

实际上,在您的情况下,您甚至可以减少所需的回复数量 rm -ri ./?,因为你的“坏”文件只有一个字符长。


31
2018-01-21 20:13



select f in ?; do rm -i "$f"; break; done 拥有所有的好处 -i,没有必须回答的痛苦 no 领导不受欢迎的人或错误地回答你想要保留的人。 - bishop
在OP的情况下,它是一个目录,而不是一个文件。 rmdir ?/ 将删除所有空的单字符目录,并抱怨其他人非空。 - Peter Cordes
@bishop:哇,我甚至都不知道 select 存在,非常整洁! - Matteo Italia
@PeterCordes:wops,我没注意到我们在谈论目录;我补充道 -r (和 ./  - 不幸的是,我的例子总是很容易忘记 rmdir 不支持 -i 旗。尽管如此,我认为在这种情况下,最好的方法是结合主教和你的评论。 - Matteo Italia
@MatteoItalia select 只存在于某些shell中,这可能就是为什么你没有碰到它 - 脚本和解决方案本来是可移植的避免它,所以我们不太可能“在野外”看到它。 - mtraceur


一种选择是用其他东西查找文件名 ls。如果你知道它是由逐字产生的 Ctrl键+C,你可以找到使用a生成的ASCII字符 控制字符表,或者像Python提供的更友好的界面:

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

另一种选择是查看输出的十六进制转储 ls,使用例如 hexdump

然后你可以用(例如)这个bash命令删除该文件:

rmdir "$(printf '\x03')"

(只有当您尝试打印的角色在您的角色中时,才需要双引号 IFS 变量,如 \x20 要么 \x0A,但引用命令替换是一个好习惯,除非你知道你希望shell执行字段拆分等。)


23
2018-01-21 18:51



也 cat -v (加 man ascii)可以帮助第一部分。 - Matteo Italia
......或者你用 os.rmdir('\x03') 直接来自Python shell。 - moooeeeep


通常在这种情况下很容易想出一个 通配符模式 与相关文件匹配。

在你的情况下,这将是简单的 ? (将所有文件名与一个字符匹配)。

只需检查它是否与您想要的完全匹配:

ls -ld ?

然后删除目录:

rmdir ?

你也可以把它结合起来 标签完成。你可以输入

rmdir ?

并按Tab键,例如在bash中它将被替换为

rmdir ^C/

然后你可以按Enter键,它会做你想要的。


15
2018-01-21 21:02





您可以使用Midnight Commander(mc)删除文件 - 只需使用向上/向下按钮选择并按F8。

当文件名由于编码而有奇怪的字符时,偶尔也会这样做。


11
2018-01-21 20:29



或者几乎任何其他文件管理器。 - Stig Hemmer
@StigHemmer当然,有些人比其他人更好地显示某些文件名。可能答案可以解释为什么MC与少数选择其他产品相比是最佳选择。我不知道,因为我从未使用它。 - can-ned_food


另一种方式:使用 stat 获取目录名称的转义表示:

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

现在您知道了文件名的表示,因此您可以使用名称删除文件 printf

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

或者,如果你使用bash,你可以避免 printf

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

7
2018-01-22 10:25



顺便说一句,如果shell是bash, $'\x03' 比调用printf简单。 FreeBSD sh也是如此,它扩展到POSIX shell上,带有一些美味的功能。 - Netch
@Netch关于bash的好点 $'...',但我总是避免从八进制到十六进制的无用转换。例如。如果文件被命名怎么办? '\111' (在 stat 输出)?你还能用它删除它吗? $'\x49'?更好地使用相同的序列 stat 给了你:在OP的情况下, rmdir $'\003'。 - Ruslan


一个对我有用的解决方案是:

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

循环浏览可用文件,直到找到要删除的文件。

但你确实需要拥有 必要的设置 在你的shell中工作。


6
2018-01-22 08:31



^ C在标签序列中真的很早,所以+1给你。 - joshudson