
我正在尝试使用自动“美化”脚本declare -f function
简而言之:给定一个 bash 脚本foo
,您显然可以通过在 bash 中执行以下操作来“自动”缩进它:
MAGIC () { ...here you copy/paste the whole foo script... ; } ; declare -f MAGIC
我在下面提供了一个示例脚本,它可以为您作为输入提供的任何脚本执行此操作。
我的问题是:使用包含函数的主要注意事项是什么declare -f
?
- 有什么特殊危险吗?
- 函数嵌套数量限制? (我可以在脚本中使用函数,它们也可以愉快地缩进,但是我可以深入多少层?)
- “将无法做到这一点/解释那个/...”? (看起来 awk 脚本变得很好,甚至缩进了一点(主脚本与脚本的其余部分对齐)......但是什么(其他)事情可能会造成问题?
- 会丢失一些信息吗?我注意到:它删除了空行和注释(
# ...
),但它还丢弃/修改了什么?
我想先得到您的输入,然后才能使用下面的“缩进”脚本重新缩进一堆 bash 脚本...
这是我的第一次尝试,欢迎评论(以及对上述问题的回答):
#!/usr/bin/bash
# parameters: $@ = bash (only) scripts that need reindentations.
for script in "$@" ; do
tmpfile="${script}.BEAUTIFY.tmp"
finalfile="${script}.BEAUTIFY"
# optionnal temporisation...
echo "I am about to create ${script}.BEAUTIFY from the bash (I hope) script: ${script} . Press return if OK, ctrl-C if not"
read temporisation
# we output the following commands into a pipe to a subshell bash:
{ sleep 1
echo "
# declare surrounding function . The script has to be bash, but can contain also functions, etc.
# Will lose # comments and blank lines, but maybe also other things... hence the Question on unix.se
ODBEAUTIFIER () {
$(cat "$script")
}
# print if via declare -f, to pretiffy it
declare -f ODBEAUTIFIER > \"${tmpfile}\"
# then get rid of the surrounding ODBEAUTIFIER function:
tail -n +3 \"${tmpfile}\" | tac | tail -n +2 | tac | sed -e 's/ //' > \"${finalfile}\"
# and displays the resulting file
ls -l \"${script}\" \"${finalfile}\"
\rm \"${tmpfile}\" ; # that rm has a backslash to avoid aliases to rm -i
"
} | bash ; # that sub- bash receives the input and interprets it
done
注释/编辑:有一种解决方法(但有许多警告和危险)可以避免“声明 -f 将丢失以 # 开头的注释”:但它似乎分散了注意力(...至少有一个坚持的用户,请参阅下面的评论 ^^)主要问题(即使很难,我引用了解决方法的许多警告,我更喜欢删除上面提到的内容,因为它根本不是问题的重点。好奇的人可以参考之前的编辑^^)
答案1
将脚本作为函数读取然后通过管道传输到另一个 shell 存在安全风险:如果输入文件包含不匹配的}
,则后面的任何内容都将被执行(并从输出中省略)。
无法匹配的情况}
可能会意外或恶意发生。它通常会导致 bash 报告语法错误,但攻击者可以通过用另一个未完成的函数结束文件来隐藏此错误(对运行美化脚本的用户来说):
}
echo "insert shellcode here" > ~/RCFILE
function end_func {
true
不太重要:
您提到它会丢失以
#
.开头的注释。这包括打开#!/bin/...
,因此它可能会阻止输出文件运行。sed -e 's/ //'
删除任意行中的前 4 个空格。那些是通常前面的 4 个空格declare
。但declare
不会在此处文档的行之前插入空格,因此这可能会删除原始文档的其他空格。您可以使用
head -n -1
代替tac | tail -n +2 | tac
.或者您可以删除两个tail
s 并使用sed '1,2d;$d'
.