背景
一个 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/