在从单行 (bash) 命令创建文件的目标中,目标是输出任何文本文件的内容 - 在本示例中为 bash 脚本 - 并将每一行包装在能够输出同一行的命令中粘贴在终端窗口中时。
示例源输入文件:
Line 1
Line 2
Line 3
示例所需的输出:
echo 'Line 1';echo 'Line 2';echo 'Line 3';
注意:只要源是人类可读的,是否使用 或其他命令来创建输出并不重要printf
。echo
一个障碍是单引号,它不会被重新创建。因此使用形式$'string',这是特殊处理的。该单词扩展为字符串,并按照 ANSI C 标准的规定替换反斜杠转义字符。
另一个要求是在新文件中从旧文件重新创建制表符。因此希望用 \t 替换 <\tab> 字符。
我们尝试这样做sed
或tr
失败。如何用转义符 \t 替换制表符,并且仍然能够输出带有原始引号的行?
输入文件 /Library/Scripts/BootRepairMount.sh 包含:
$ cat /Library/Scripts/BootRepairMount.sh
#!/bin/bash
sleep 18
for OUTPUT in $(diskutil list | grep ': Apple_HFS' | awk '{ print $NF }')
do
if [[ -z $(df -lnh | grep /dev/$OUTPUT) ]]; then
echo "$OUTPUT is not mounted, repair and mount"
diskutil repairVolume $OUTPUT
diskutil mount $OUTPUT
fi
done
我们可以创建的最好的 shell 单行命令是:
$ oldifs=$IFS;printf '\n';printf '{';while IFS= read -r p;do [[ "$p" == *"'"* ]] && echo -n "echo $'$p';" || echo -n "echo '$p';"; done < /Library/Scripts/BootRepairMount.sh | tr '\t' '\134\164';printf '}';printf '\n\n';IFS=$oldifs
返回此错误输出:
{echo '#!/bin/bash';echo 'sleep 18';echo $'for OUTPUT in $(diskutil list | grep ': Apple_HFS' | awk '{ print $NF }')';echo 'do';echo '\if [[ -z $(df -lnh | grep /dev/$OUTPUT) ]]; then';echo '\\echo "$OUTPUT is not mounted, repair and mount"';echo '\\diskutil repairVolume $OUTPUT';echo '\\diskutil mount $OUTPUT';echo '\fi';echo 'done';}
期望的输出是:
{echo '#!/bin/bash';echo 'sleep 18';echo $'for OUTPUT in $(diskutil list | grep ': Apple_HFS' | awk '{ print $NF }')';echo 'do';echo '\tif [[ -z $(df -lnh | grep /dev/$OUTPUT) ]]; then';echo '\t\techo "$OUTPUT is not mounted, repair and mount"';echo '\t\tdiskutil repairVolume $OUTPUT';echo '\t\tdiskutil mount $OUTPUT';echo '\tfi';echo 'done';}
Bash 一行命令版本 2
$ oldifs=$IFS;printf '\n';printf '{';while IFS= read -r p;do [[ "$p" == *"'"* ]] && printf 'printf $'\''%q'\'';' "$p" || printf 'printf '\''%q'\'';' "$p"; done < /Library/Scripts/BootRepairMount.sh;printf '}';printf '\n\n';IFS=$oldifs
返回重度转义的输出:
{printf '\#\!/bin/bash';printf 'sleep\ 18';printf $'for\ OUTPUT\ in\ \$\(diskutil\ list\ \|\ grep\ \':\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ Apple_HFS\'\ \|\ awk\ \'\{\ print\ \$NF\ \}\'\)';printf 'do';printf '$'\tif [[ -z $(df -lnh | grep /dev/$OUTPUT) ]]; then'';printf '$'\t\techo "$OUTPUT is not mounted, repair and mount"'';printf '$'\t\tdiskutil repairVolume $OUTPUT'';printf '$'\t\tdiskutil mount $OUTPUT'';printf '$'\tfi'';printf 'done';}
永远不会在 Mac OS X 10.7.5 中恢复到其原始值。
printf '\#\!/bin/bash';
输出:
\#\!/bin/bash
也:
echo -e '\#\!/bin/bash'
确实输出未转义的值
\#\!/bin/bash
-e
echo
根据其man
页面,它不是 Mac OS X 10.7.5 命令的有效命令开关。