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

Mau*_*043 128 freebsd filesystems

我打错字了:

$ history
169 9:34    la /usr/local/etc/
170 9:35    sudo mkdir ^C
171 9:36    sudo mkdir /usr/local/etc/dnsmasq.d
Run Code Online (Sandbox Code Playgroud)

现在我有一个名为 ^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
Run Code Online (Sandbox Code Playgroud)

% ls -i
3611537 ?   3611534 bin
Run Code Online (Sandbox Code Playgroud)

我想删除这个文件。我尝试mv使用 tab-completion 时它显示我:

% mv
^C/  bin/
Run Code Online (Sandbox Code Playgroud)

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

Håk*_*ist 191

^V( ctrl+ v) 用作下一次按键的一种转义序列,插入关联的值而不是采取通常关联的任何操作。

利用这个,^V^C( ctrl+ v, ctrl+ c) 应该可以在终端中输入您的困难文件名。

  • 这可能是 OP 最初打错字的方式。V 和 C 在键盘上紧挨着。 (41认同)
  • 或者他们试图在 bsd 终端上使用 Windows 剪贴板。 (14认同)
  • @JoelCoel 习惯永远不会消失! (2认同)
  • 有趣的是,`^V^C` 在 Zsh 行编辑器中*不起作用*;[quoted-insert](http://zsh.sourceforge.net/Doc/Release/Zsh-Line-Editor.html) 小部件(在页面中搜索`^V`)明确不插入中断字符。Jakob 的回答(使用 printf)可能是一种在 shell 参数中提供控制字符的更便携的方式。 (2认同)

bis*_*hop 90

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

$ ls -i1
290742 foo
293246 ^C
$ find . -inum 293246 -delete
Run Code Online (Sandbox Code Playgroud)

不管你做什么,偏偏,不要把-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
$ 
Run Code Online (Sandbox Code Playgroud)

恭喜,您刚刚清除了所有文件。随着find参数顺序很重要

  • 不要将 `-delete` 放入命令句号中,直到你在没有 `-delete` 的情况下运行该命令以检查它是否找到了你想要的东西。 (39认同)
  • @detuur:顺序影响结果。见编辑。 (11认同)
  • @Kaz 使用 `-print` 而不是 `-delete` 是一个很好的测试。 (9认同)
  • 为什么不把 `-delete` 放在 `-inum` 之前?这只是一种预防措施,以防您过早按下 Enter 键,还是参数的顺序实际上会影响结果? (2认同)
  • @Kaz 在命令中心添加 -delete 不会有太大帮助 (2认同)
  • @HankCa:`find` 并没有真正区分“查询”和“动作”子表达式。`-delete` 和 `-print` 是总是返回 `true` 的函数,只是碰巧有一些副作用;这允许构建任意复杂的表达式。这有点像问“为什么在 C `!unlink(filename) &amp;&amp; strcmp(filename,"temp.txt")==0` 中总是删除 `filename`” - 你把你的表达式写反了,这不是语言错误做你所要求的。OTOH,鉴于有多少文件因对“查找”工作的误解而死亡,也许它的界面*可能*更用户友好。 (2认同)

Mat*_*lia 32

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

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

  • `在 ? 中选择 f; 做 rm -i "$f"; 休息; done` 具有 `-i` 的所有优点,无需为导致不受欢迎的人回答 `no` 或错误地回答你想要保留的人的痛苦。 (8认同)
  • 在 OP 的情况下,它是一个目录,而不是一个文件。`rmdir ?/` 将删除所有空的单字符目录,并抱怨其他非空目录。 (6认同)
  • @bishop:哇,我什至不知道存在`select`,非常整洁! (2认同)

Jak*_*kob 23

一种选择是使用除ls. 如果您知道它是由逐字Ctrl+ 生成的C,您可以找到使用控制字符表生成的 ASCII字符,或者使用更友好的界面(如 Python 提供的界面):

>>> import os
>>> os.listdir('.')
['\x03', ...]
Run Code Online (Sandbox Code Playgroud)

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

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

rmdir "$(printf '\x03')"
Run Code Online (Sandbox Code Playgroud)

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

  • ...或者您直接从 Python shell 使用 `os.rmdir('\x03')`。 (13认同)
  • 另外`cat -v`(加上`man ascii`)可以帮助第一部分。 (2认同)

Juk*_*ela 15

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

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

只需检查它是否真的符合您的要求:

ls -ld ?
Run Code Online (Sandbox Code Playgroud)

然后删除目录:

rmdir ?
Run Code Online (Sandbox Code Playgroud)

您还可以将其与选项卡完成相结合。你可以输入

rmdir ?
Run Code Online (Sandbox Code Playgroud)

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

rmdir ^C/
Run Code Online (Sandbox Code Playgroud)

然后你可以按回车键,它会做你想做的事。


小智 11

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

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

  • 或者几乎任何其他文件管理器。 (4认同)

Rus*_*lan 7

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

$ stat *|grep File:
  File: ‘\003’
Run Code Online (Sandbox Code Playgroud)

现在您知道文件名的表示形式,因此您可以使用printf以下命令按名称删除文件:

$ rmdir -v "$(printf '\003')"
rmdir: removing directory, ‘\003’
Run Code Online (Sandbox Code Playgroud)

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

$ rmdir -v $'\003'
rmdir: removing directory, ‘\003’
Run Code Online (Sandbox Code Playgroud)


joe*_*dle 6

对我有用的解决方案是:

rm ./[Tab][Tab][Tab]...
Run Code Online (Sandbox Code Playgroud)

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

但是您确实需要在 shell 中进行必要的设置才能使其工作。


Kon*_*bas 5

最简单的方法是将所有内容移动到临时目录,然后rm -r DIRNAME.

  • 对您来说,这真的比接受的答案更容易吗? (7认同)
  • @chicks `^V` 需要特定的知识,同时移动文件和删除父目录可以从基础知识中获得。 (6认同)
  • Ctrl+V 是危险的模棱两可取决于您的确切工作环境......一些终端模拟器可能会将其解释为粘贴。如果您的粘贴缓冲区包含您不想删除的内容的名称 - 以及换行符,您可能正在查看问题。 (5认同)
  • @chicks:这实际上并不是一个糟糕的答案。我已经看到 ^V^C 不起作用,所以有人可能会卡住。 (2认同)