bash 脚本使用声明 -f 自动美化

bash 脚本使用声明 -f 自动美化

我正在尝试使用自动“美化”脚本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.或者您可以删除两个tails 并使用sed '1,2d;$d'.

相关内容