如何测试 shell 脚本的文件处理稳健性?

如何测试 shell 脚本的文件处理稳健性?

我写了一个处理一些“常规”文件名的 shell 脚本,但我读过为什么我的 shell 脚本会因为空格或其他特殊字符而卡住?为什么你不应该解析 ls 的输出我希望它更加强大并处理任何有效的文件名(和/或目录名)。如何创建文件和目录的测试台来运行我的脚本?

答案1

创建一个单独的目录来播放(主要是为了方便以后清理);$TMPDIR如果已设置,则使用值,否则/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

以上归功于帕特里克。两个十六进制代码是 UTF-8 空格分隔符,称为坚果羊肉; “在双向上下文中,它充当空白并且不进行镜像。在某些情况下,该字形可能会与其他 20 个字形混淆。”

创建一个普通文件和一个如果被视为 glob 则将扩展到第一个文件的文件:

touch -- x '[x]' 

以上归功于乌普斯·Q·温布利

与此相类似:

touch -- 'a?b' 'a*b'

以上归功于戴夫·汤普森_085在这里的评论中。

touch -- foo\`echo\ malicious\`bar

以上归功于神客

如果在 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.

转义 glob 的文件.[!.]* *(有时用于扩展隐藏和非隐藏文件):

touch ..foo ...

相关内容