java - 抑制 Shell 脚本中的关键字扩展

标签 java bash shell svn escaping

背景

一个 shell 脚本生成许多 Java 源文件。源文件有一个特定的标题注释,其中包含 Subversion 关键字。目标是在不更改隐藏在其中的源文件头的情况下 checkin shell 脚本。

问题

shell脚本包含自己的header,应该有关键字展开:

#!/bin/bash
#
#  Revision Control Information
#  File:                $Id:: autogenerate.sh 3142 2016-08-26 18:50:21Z USERNA#$
#  Date of Last Commit: $Date:: 2016-08-26 11:50:21 -0700 (Fri, 26 Aug 2016)   $
#  Revision Number:     $Rev:: 3142                                            $
#  Last Commit by:      $Author:: USERNAME                                     $

这部分有效。失败的部分是稍后在 shell 脚本中包含注释时:

cat <<EOT >> $FILENAME_IMPL
/*
 * *********************************************************************
 *  Revision Control Information
 *  File:                $Id::                                         $
 *  Date of Last Commit: $Date::                                       $
 *  Revision Number:     $Rev::                                        $
 *  Last Commit by:      $Author::                                     $
 *
 * **********************************************************************
 */
package com.company.pkg;
EOT

将shell脚本检入版本库时,第一组关键字正确展开;但是,Java 注释 header 的关键字也得到了扩展。我原以为一旦关键字被扩展,相同关键字的后续匹配将被忽略。事实并非如此。

检查存储库会更改将添加到每个 Java 源文件顶部的注释:

cat <<EOT >> $FILENAME_IMPL
/*
 * *********************************************************************
 *  Revision Control Information
 *  File:                $Id:: autogenerate.sh                                 $
 *  Date of Last Commit: $Date:: 2016-08-26 11:50:21 -0700 (Fri, 26 Aug 2016)  $
 *  Revision Number:     $Rev:: 1234                                           $
 *  Last Commit by:      $Author:: USERNAME                                    $
 *
 * **********************************************************************
 */
package com.company.pkg;
EOT

Java 源文件的文件名不会是“autogenerate.sh”,而是“ClassName.java”。

澄清

为了澄清,请考虑以下名为 autogenerate.sh 的简单 shell 脚本:

#!/bin/bash
#  File:                $Id:: $

FILENAME_IMPL=ClassName.java

cat <<EOT >> $FILENAME_IMPL
/* File:                $Id:: $
 */
package com.company.pkg;
EOT

将脚本 checkin 存储库后,其内容变为:

#!/bin/bash
#  File:                $Id:: autogenerate.sh $

FILENAME_IMPL=ClassName.java

cat <<EOT >> $FILENAME_IMPL
/* File:                $Id:: autogenerate.sh $
 */
package com.company.pkg;
EOT

第一个 $Id:: 关键字被正确替换。第二个 $Id:: 关键字应该被忽略。换句话说,当我将脚本 checkin 存储库时,我希望看到:

#!/bin/bash
#  File:                $Id:: autogenerate.sh $

FILENAME_IMPL=ClassName.java

cat <<EOT >> $FILENAME_IMPL
/* File:                $Id:: $
 */
package com.company.pkg;
EOT

想法

转义关键字没有帮助。例如:

cat <<EOT >> $FILENAME_IMPL
/* File:                \$Id:: $
 */
package com.company.pkg;
EOT

问题

在 checkin Subversion 存储库时,您将如何防止或抑制除第一个匹配关键字之外的所有关键字扩展?

最佳答案

尝试:

xId='$Id'; xDate='$Date'; xRev='$Rev'; xAuthor='$Author'
cat <<EOT >> "$FILENAME_IMPL"
/*
 * *********************************************************************
 *  Revision Control Information
 *  File:                $xId::                                         $
 *  Date of Last Commit: $xDate::                                       $
 *  Revision Number:     $xRev::                                        $
 *  Last Commit by:      $xAuthor::                                     $
 *
 * **********************************************************************
 */
package com.company.pkg;
EOT

当 subversion 处理这个脚本时,它会忽略 $xId::$ 因为 xId 不是可识别的关键字。当脚本运行时,$xId 将扩展为一个 shell 变量,文件 $FILENAME_IMPL 将具有正确的 $Id::$其中的关键字结构。

顺便说一句,这解决了另一个问题:在原始代码中,$Id$Date 等在编写之前被 shell 扩展了到 $FILENAME_IMPL。使用此代码,$FILENAME_IMPL 中的输出将是您所期望的。

关于java - 抑制 Shell 脚本中的关键字扩展,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39232624/

相关文章:

java - JTable 图像渲染在应用程序中承受过多负载

Git可以 pull 好但不能推送 "could not read username"

mongodb - 用于编辑 MongoDB 配置文件的 Bash 脚本

linux - 如何在字符串的第一次出现和最后一次出现之间裁剪非常大的文本文件? (Linux)

linux - SVN 提交后 Hook 发布网站?

java - 使用 Java 将 XSLT 与 import/include 语句合并

java - 在java中填充未初始化的数组? (或解决方法!)

java - Selenium Webdriver - 取消选中复杂表格中的所有复选框

linux - 在 bash 中对多行运行统计

linux - 数字验证在 Linux shell 脚本中无法正常工作