我有一个运行JAR的initctl服务,我需要确保在更新代码后重新启动。
我知道我可以只写一个带有版本的文本文件并检查它,但是我想知道是否有一种方法可以使用带有initctl状态ServiceNameHere的版本标签构建一个可以查看的版本标签?
任何更好的选择也将有所帮助!
答案 0 :(得分:1)
正确构建的.jar的版本存储在其清单或模块描述符中。 .jar文件实际上只是一个zip文件,具有一个或多个特定于Java的特殊条目,其中最重要的是META-INF/MANIFEST.MF
,这是一个纯文本文件,称为清单,其中包含有关.jar文件内容的信息。
可能存在多个standard attributes(尽管自定义属性是允许的,并且实际上是常见的)。标准的一种是Implementation-Version
。
因此,要确定.jar文件的版本,可以使用:
unzip -p /path/to/jar META-INF/MANIFEST.MF | sed -n -e 's/^Implementation-[Vv]ersion: //p'
如果您的.jar文件是Java 9+模块,则清单属性将被忽略,因此上述方法无效。在这种情况下,您需要提取模块描述符:
jar -d -f /path/to/jar | sed -n -e 's/^[^@]*@\([^ ][^ ]*\).*/\1/p'
要检查您要运行的.jar是否与上次运行的.jar具有相同的版本,请将其存储在/var
下。例如:
versionfile=/var/local/last_jar_version
version=`unzip -p /path/to/jar META-INF/MANIFEST.MF | sed -n -e 's/^Implementation-[Vv]ersion: //p'`
# For modules: version=`jar -d -f /path/to/jar | sed -n -e 's/^[^@]*@\([^ ][^ ]*\).*/\1/p'`
if [ -f "$versionfile" && "$version" = `cat "$versionfile"` ]
then
echo Running same version of jar as last time.
else
echo Running a different jar version: "$version"
fi
printf %s "$version" > "$versionfile"
更正的情况:从a line in a manifest may not be longer than 72 bytes (not characters)开始,对于长度超过48个ASCII字符的非模块jar版本,此操作将失败。 ({Implementation-Version:
是24字节,而72 − 24 =48。)我从没见过那么久,但是我怀疑它们在那里。