【问题标题】:Parsing heredoc comments in BASH script在 BASH 脚本中解析 heredoc 注释
【发布时间】:2013-11-26 00:37:52
【问题描述】:

我有一组 Bash 脚本,希望能够解析它们以提取它们的定义。

如果我在脚本 (ab) 中使用 heredocs 来形成我的描述,如下所示,这是否会带来任何好处:

#!/bin/bash

DESCRIPTION = <<EOD

This nifty script does x, y and sometimes z

EOD

# rest of script...

结束:

#!/bin/bash

# Description
# ==========
#
# This nifty script does x, y and sometimes z 

# rest of script...

即,我是否有一种简单的方法可以从 Bash 脚本中提取变量,或者我是否需要编写一个脚本来解析文件以获取从 # Description 到下一个空白行的格式正确的描述块?

更新

很多很好的答案。我选择了最适合我的用例和偏好的那个,但它们都是 Bash 评论实现的好例子。

【问题讨论】:

    标签: bash syntax coding-style


    【解决方案1】:

    在提取信息的难度方面没有实际差异。 cmets 具有不可执行的轻微优势,因此不创建 $DESCRIPTION 变量会带来边际性能优势,但您很难衡量它。

    当然,还有一个额外的问题是显示的 heredoc 语法不是有效的 shell。您需要考虑:

    cat >/dev/null <<EOD
    ...
    EOD
    

    或者也许(但也许不是——除非你想在脚本本身中使用$DESCRIPTION):

    DESCRIPTION=$(cat <<EOD
    ...
    EOD
    )
    

    或者,也许更好:

    : DESCRIPTION = <<EOD
    ...
    EOD
    

    冒号命令是无操作的;它评估它的论点并成功。与cat 中的任何一个变体相比,我更喜欢这个。 DESCRIPTION= 参数是干扰词;您可以省略其中一个或两个而不影响脚本。您可能还想考虑在第一个 EOD 周围使用引号:

    : <<'EOD'
    ...$(cat this is not executed)...
    EOD
    

    请注意,: 命令和第一个 cat 替代项不会初始化 shell 变量 $DESCRIPTION。如果这很重要,您会被命令替换 $(...) 版本卡住,注意有两行标记分配结束。

    【讨论】:

      【解决方案2】:

      我想这就是你想要的。

      #!/bin/bash
      
      [ "$1" = "DESCRIPTION" ] && cat <<EOD && exit
      
      Hello, this is the ${1}
      
      This nifty script does x, y and sometimes z
      The nice thing is that linebreaks will be preserved.
      This makes it a "useful"  'here document'
      
      no problem with 'single' or "double" quotes
      nothing matters much except variables
      
      EOD
      
      
      rest of script...
      

      效果很好:-)

      【讨论】:

        【解决方案3】:

        让您的描述行以唯一标识符开头,如下所示:

        (例如我们取字符:#>)

        #!/bin/bash
        
        #> This is a description header
        #> 
        #> This program will do z, y and X
        #> because I want that
        
        # this is normal comment
        
        .... rest of program 
        or some other stuff
        

        获取您的描述:

        grep "^#>" myscript.sh
        

        将导致:

        #> This is a description header
        #> 
        #> This program will do z, y and X
        #> because I want that
        

        这比尝试获取要容易得多:

        1. 文档中的变量 (这只能通过部分采购来完成......这是另一罐蠕虫。)

        2. 尝试检索 (EOD) 标记之间的部分

        3. 尝试启发式地确定哪个是评论或哪个是描述。

        【讨论】:

          【解决方案4】:

          拥有一个包含描述的变量的想法非常有趣。

          从程序中检索它的最佳方法是让程序为您打印它。 不要只使用单引号或双引号,因为这是在变量中合并换行符的唯一方法。 我们也可以通过直接回显字符串来绕过对变量的需求。

          你可以:

          #!/bin/bash
          #---------------------------------
          [ "$1" = "DESCRIPTION" ] && echo '
          
          Hello,
          
          This nifty script does x, y and sometimes z
          The nice thing is that linebreaks will be preserved.
          This makes it as useful as a here document
          
          you can choose between single or double quotes
          
          ' && exit
          #---------------------------------
          
          rest of script...
          

          它看起来不是很漂亮(虽然也不错),但是检索描述非常简单,而且不需要额外的工具:

          scriptname.sh DESCRIPTION 
          

          【讨论】:

          • 我真的很喜欢它不需要额外的工具来从 CLI 中获取描述。有什么方法可以调整它以忽略描述文本中的单引号而不用担心格式?
          • 是的,如果你使用双引号作为开始和结束标记,你可以在文本中使用单引号(反之亦然)。
          • 还有另一种方式。我将把它作为另一个答案发布。
          猜你喜欢
          • 2013-07-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-12-06
          • 2013-08-30
          • 2011-09-06
          相关资源
          最近更新 更多