我已经编写了一个处理一些“常规”文件名的shell脚本,但是我读了为什么我的shell脚本为什么会在空白或其他特殊字符上出现问题?以及为什么不应该解析ls的输出,我希望它更加健壮并处理任何有效的文件名(和/或目录名)。如何创建文件和目录的测试平台来运行脚本?
我已经编写了一个处理一些“常规”文件名的shell脚本,但是我读了为什么我的shell脚本为什么会在空白或其他特殊字符上出现问题?以及为什么不应该解析ls的输出,我希望它更加健壮并处理任何有效的文件名(和/或目录名)。如何创建文件和目录的测试平台来运行脚本?
Answers:
创建一个单独的目录进行播放(主要是为了便于以后清理);它使用$TMPDIR
if 的值设置,否则/tmp
:
mkdir "${TMPDIR-/tmp}/testing"
cd "${TMPDIR-/tmp}/testing"
创建单独的文件,但由于空白(空格,制表符,换行符,回车符,退格键)而看起来彼此相似:
touch -- a b 'a ' 'b ' 'a b' 'a b' $'a\bb'
touch -- a$'\xe2\x80\x82'b a$'\xe2\x80\x83'b a$'\t'b a$'\n'b a$'\r'b
以上归功于Patrick。这两个十六进制代码是UTF-8空格分隔符,称为螺母和羊肉;“在双向上下文中,它充当空白并且没有镜像。在某些情况下,该字形可以与其他20个字形混淆。”
创建一个普通文件,如果将其视为全局文件,则将其扩展到第一个文件:
touch -- x '[x]'
与此相类似:
touch -- 'a?b' 'a*b'
在此处的评论中,将以上内容归功于dave_thompson_085。
touch -- foo\`echo\ malicious\`bar
以上归功于Godlygeek。
如果在shell上下文中进行评估,则文件名将扩展为不同的名称(可能任意执行!):
touch '$( echo boom )'
用:
touch -- single\'quote double\"quote back\\slash
捕获尝试将文件名放在引号中而不转义引号的尝试。
touch -- -a -b -c -r -R - a=x
创建一个命名管道和符号链接(以创建非“常规”文件):
mkfifo fifo
ln -s a alink
创建名称中包含各种空格的子目录,以及其中的令牌文件:
mkdir subdir "subdir 1" "subdir 2" "subdir 3 " subdir$'\n'4
touch subdir/file0 "subdir 1"/file1 "subdir 2"/file2 "subdir 3 "/file3 subdir$'\n'4/file4
创建仅包含*
(可能有问题删除)的文件名,该文件名仅包含(常规!)空间,无效的符号链接,循环自身的符号链接以及带有返回父目录链接的子目录:
touch -- '*' '**' '***' ' '
ln -s /does/not/exist dead
ln -s loop loop
mkdir subdir_with_link
(cd subdir_with_link && ln -s .. parent)
更多杂项文件名。最后两个是“小数斜杠”和“除法斜杠”的unicode。
touch -- '(' '!' '!!' $'\xe2\x81\x84' $'\xe2\x88\x95'
斯科特的想法:
touch -- '-' '--' ';' '&' '|' '<' '>' '$' ')' '{' '}' = \\ '!' '#' '{a,b}'
在某些语言环境中无害但在其他语言环境中有危险的字符:
touch $'X\xa0Y' # non-breaking space in iso8859-1 which is considered
# "blank" and "space" in some locales
touch $'\xa3\x5c' $'\xa3\x60' # α and ε in BIG5 or BIG5-HKSCS charset, but
# �\ and �` in ASCII
在某些语言环境中排序相同的字符:
touch ① ② # sorts the same in GNU locales, order non-deterministic.
逃脱.[!.]* *
全局文件的文件(有时用于扩展隐藏文件和非隐藏文件):
touch ..foo ...
a?b
和a*b
(报价当然)。@muru:字节序列E2 80 82/83是U + 2002 EN SPACE和U + 2003 EM SPACE的UTF-8编码
-
并且--
,尽管根据脚本的要求,在没有前导的情况下可能无法访问它们./
。我很惊讶,也有非水珠shell特殊字符等几种,像;
,&
,|
,<
,>
,$
,(
,)
,{
,}
,=
,\
,!
,和#
-例如,{a,b}
。