java – 在Shell脚本中抑制关键字扩展

背景

shell脚本生成许多Java源文件.源文件具有包含Subversion关键字的特定标题注释.目标是签入shell脚本而不更改隐藏在其中的源文件头.

问题

shell脚本包含自己的标头,应该有关键字扩展:

#!/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注释标题的关键字也会扩展.我曾想过,一旦关键字被扩展,相同关键字的后续匹配将被忽略.不是这种情况.

检入存储库会更改将添加到每个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

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

#!/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 ::关键字.换句话说,当我将脚本检入存储库时,我想看到:

#!/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

在检查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和其他内容在被写入$FILENAME_IMPL之前由shell扩展.使用此代码,$FILENAME_IMPL中的输出将是您所期望的.

上一篇:php – symfony 1.4解释并且不会在模板中使用fetchOne()显示html标签


下一篇:正确的方法来逃避包含PHP变量的HTML字符串中的引号