最近在NAS上遇到了一个头痛的问题,由于NAS的Shell功能有限,SSH连过去之后虽然能显示中文,但是却无法输入,复制粘贴也不行。于是上网到处找,没想到中文搜索竟一无所获,最终找到了英文的,在这里搬运翻译一下。
虽说我的情况是删除中文文件,但其实这些情况适用于任何特殊字符(比如还有>
(输出重定向)、*
(通配符)、-
(命令选项)、$
(变量引用)、(空格,分隔参数和选项)等),也可以举一反三用在其他操作上。
把文件名放到引号中
这可以说是最基本的方法了,Shell中引号表示字符串,所以有些字符放到引号中就不具有本来在Shell命令中的功能了。单引号'
或者双引号"
都可以,但注意要配对。例如删除名为my file
的文件:
rm "my file"
用反斜杠转义
用反斜杠\
转义字符相信编写过程序的都不陌生,有的特殊字符是可以用反斜杠转义的,转义之后就失去在Shell命令中的功能了。实际上如果经常用Tab来自动完成命令的话就会发现,自动完成的就是用反斜杠来转义的。例如删除名为[my file]
的文件:
rm \[my\ file\]
在文件名前加上./
./
表示当前目录,有的字符如果出现在空格后面就有特殊含义(比如-
表示命令选项),但加上./
之后就不是了。比如删除名为-my-file
的文件:
rm ./-my-file
在文件名前加上--
--
表示结束命令选项,在其之后的字符都被视为参数。当然,--
两边要加上空格,而且只对文件开头的是-
的有效,其他特殊字符还是要用其他办法。比如删除名为-my-file
的文件:
rm -- -my-file
用inode编号删除
上面的方法只能针对某些特殊字符,对于我在本文开头说到的情况无能为力,但是我们还有最终解决方案。关于什么是inode就不详细说了,反正这里只要知道在一个文件系统上每个文件或目录都有一个inode编号。这个编号可以通过ls
的-i
选项来查看,为了看得清楚,我们再加上选项-1
来让一项结果占一行。
li -i1
比如我这里有三个特殊文件名的文件file
、-file
、$file
的结果如下:
63184461 file
63181495 -file
63184295 $file
文件名前面的数字就是inode编号了。
可是rm
并不支持用inode来删除,怎么办呢,这里就要请出另一个命令了,这就是find
。这是个查找文件的命令,它有个选项-inum
可以指定inode编号,还有个选项-delete
可以直接删除文件。
find . -inum 63181495 -delete
.
表示在当前目录查找,-inum 63181495
就是查找inode编号为63181495的文件,-delete
就是将找到的文件删除。
但-delete
选项只能删除文件和空目录,要删除有文件的目录怎么办呢,这个时候就要另一个选项出场了——-exec
,表示将查找到的文件放到其后的命令中。在命令中{}
会用查找到的文件代替。
find . -inum 63181495 -exec rm -ri {} \;
rm
的选项-r
表示递归删除目录和里面的内容,-i
表示删除每一个项之前都弹出提示询问以免误删。
于是,目录被我快乐地删除掉了。