简体   繁体   中英

Suppress Keyword Expansion in Shell Script

Background

A shell script generates a number of Java source files. The source files have a particular header comment that includes Subversion keywords. The goal is to check-in the shell script without changing the source file headers buried within.

Problem

The shell script contains its own header, which should have keyword expansion:

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

This part works. The part that fails is when a comment is included later on in the shell script:

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

When checking the shell script into the repository, the first set of keywords are expanded correctly; however, the keywords for the Java comment header are also expanded. I had thought that once a keyword was expanded, subsequent matches of the same keyword would be ignored. This is not the case.

Checking into the repository changes the comment that will be added to the top of every Java source file:

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

The filename for the Java source won't be "autogenerate.sh", but rather "ClassName.java".

Clarification

To clarify, consider the following simple shell script called autogenerate.sh :

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

FILENAME_IMPL=ClassName.java

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

When the script is checked into the repository, its contents become:

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

FILENAME_IMPL=ClassName.java

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

The first $Id:: keyword is correctly substituted. The second $Id:: keyword should be ignored. In other words, when I check the script into the repository, I'd like to see:

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

FILENAME_IMPL=ClassName.java

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

Ideas

Escaping the keyword did not help. For example:

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

Question

How would you prevent or suppress keyword expansion for all but the first matching keyword when checking into a Subversion repository?

Try:

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

When subversion processes this script, it will ignore $xId::$ because xId is not a recognized keyword. When the script is run, $xId will be expanded as a shell variable and the file $FILENAME_IMPL will have the correct $Id::$ keyword structure in it.

This, by the way, fixes another problem: in the original code, $Id , $Date , and the others were expanded by the shell before they were written to $FILENAME_IMPL . With this code, the output in $FILENAME_IMPL will be what you expect.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM