暂时忽略此处仅作为示例使用的特定文件类型的任何问题。
给定一个包含多种类型文件的目录,如markdown格式的README文件、git版本控制文件、PEM密钥和其他随机文件类型,就可移植性甚至可读性而言,只选择目录中的PEM密钥并将其移动到任意位置的最佳方式是什么?
一个可能的选项是使用file
工具,该工具返回文件类型。例如:
$ file randomly-named-file
randomly-named-file: PEM RSA private key
从本质上讲,就可移植性或可读性而言,创建类似以下伪"代码"的测试的最佳方式是什么
if file $1 is PEM
mv $1 /some/other/dir
fi
首选Bash;不过,如果需要,perl解决方案是可以接受的。
最初的问题源于在Mac OSX平台上的使用,该平台具有较高的用例,并且需要在Linux(基于RHEL的Gentoo)平台之间进行可移植性。
file
版本是5.31,支持-print0
。
值得注意的是,file
工具显然是我想到的第一选择。如果有其他便携式解决方案,它不必使用该工具。
需要file -0
的合理实现(受libmagic的所有常见限制)可能如下所示:
#!/usr/bin/env bash
# ^^^^- NOT /bin/sh; requires bash-specific syntax.
while IFS= read -r -d '' filename && read -r type; do
type=${type#": "}
if [[ $type = *"PEM RSA private key"* ]]; then
printf 'Found file: %qn' "$filename"
fi
done < <(file -0 -- *)
-0
参数告诉file
在每个文件名之后打印一个NUL;IFS= read -r -d ''
读取到第一个NUL,因此它只消耗文件名,而read -r type
消耗每行的其余部分。
这使得可以从列表中的类型中消除名称的歧义,即使这些名称包含冒号、换行符或其他令人惊讶的字符。如果没有-0
,则需要为要测试的每个文件启动一个单独的file
副本,并附带相关的性能影响。
如果由于某种原因,您不能依赖file
,您可以尝试使用head
检查文件中的PEM文件标准头,如下所示:
for file in ./*; do
echo "Examining file: $file"
first_line=$(head -n 1 "$file")
if [ "$first_line" = "-----BEGIN ENCRYPTED PRIVATE KEY-----" ]; then
echo "Found PEM file"
mv example.pem /my/arbitrary/dir
fi
done
我用以下测试文件创建了一个小目录:
$ ls
pretend.pdf example.pem script.sh text_file.txt
针对该目录运行脚本会得到以下结果:
$ ./script.sh
Examining file: ./pretend.pdf
Examining file: ./example.pem
Found PEM file
Examining file: ./script.sh
Examining file: ./text_file.txt