如何使用Bash从JAR读取MANIFEST.MF文件

如何使用Bash从JAR读取MANIFEST.MF文件,bash,jar,manifest.mf,Bash,Jar,Manifest.mf,我需要使用bash从“some.jar”读取MANIFEST.MF maven清单文件 $ unzip -q -c myarchive.jar META-INF/MANIFEST.MF -q将禁止解压缩程序的详细输出 -c将提取到标准输出 例如: $ unzip -q -c commons-lang-2.4.jar META-INF/MANIFEST.MF Manifest-Version: 1.0 Ant-Version: Apache Ant 1.7.0 Created-By: 1.

我需要使用bash从“some.jar”读取MANIFEST.MF maven清单文件

$ unzip -q -c myarchive.jar META-INF/MANIFEST.MF
  • -q
    将禁止解压缩程序的详细输出
  • -c
    将提取到标准输出
例如:

$ unzip -q -c commons-lang-2.4.jar META-INF/MANIFEST.MF

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.7.0
Created-By: 1.5.0_13-119 (Apple Inc.)
Package: org.apache.commons.lang
Extension-Name: commons-lang
Specification-Version: 2.4
Specification-Vendor: Apache Software Foundation
Specification-Title: Commons Lang
Implementation-Version: 2.4
Implementation-Vendor: Apache Software Foundation
Implementation-Title: Commons Lang
Implementation-Vendor-Id: org.apache
X-Compile-Source-JDK: 1.3
X-Compile-Target-JDK: 1.2
或者,您可以使用
-p
而不是
-q-c

-p将文件提取到管道(标准输出)。只有文件数据被发送到stdout,文件总是以二进制格式提取,就像它们被存储一样(没有转换)


使用
解压

$ unzip -q -c $JARFILE_PATH META-INF/MANIFEST.MF
这将安静地(
-q
)读取路径META-INF/MANIFEST.MF从JAR文件(使用zip格式压缩)到stdout(
-c
)。然后,您可以通过管道将输出传递给其他命令,以回答诸如“此jar的主类是什么?”

$ unzip -q -c $JARFILE_PATH META-INF/MANIFEST.MF | grep 'Main-Class' | cut -d ':' -f 2

(这将删除所有不包含字符串
Main Class
,然后在
处拆分该行,只保留第二个字段,即类名)。当然,可以适当地定义
$JARFILE\u路径
,或者将
$JARFILE\u路径
替换为您感兴趣的JARFILE的路径。

根据您的发行版,安装
解压
包。然后简单地发布

unzip -p YOUR_FILE.jar META-INF/MANIFEST.MF
这将把内容转储到STDOUT


HTH

$tarxfosome.jar META-INF/MANIFEST.MF

x
提取并
O
重定向到标准输出


注意:似乎只适用于bsdtar,而不适用于GNU tar。

其他人已经发布了关于使用unzip-p和管道到grep或awk或任何你需要的东西的帖子。虽然这适用于大多数情况,但值得注意的是,由于MANIFEST.MF的每行72个字符的限制,您可能会对其值被拆分为多行的键进行grepping,因此很难对其进行解析。我希望看到一个CLI工具,它可以从文件中提取渲染值


以下Groovy脚本使用Java的API解析清单,避免了清单格式奇怪的断行问题:

#!/usr/bin/env groovy
for (arg in args) {
  println("[$arg]")
  jarPath = new java.io.File(arg).getAbsolutePath()
  jarURL = new java.net.URL("jar:file:" + jarPath + "!/")
  m = jarURL.openConnection().getManifest()
  m.getMainAttributes().each { k, v -> println("$k = $v") }
}
将JAR文件作为参数传递:

$ groovy manifest.groovy ~/.m2/repository/junit/junit/4.13/junit-4.13.jar
[/Users/curtis/.m2/repository/junit/junit/4.13/junit-4.13.jar]
Implementation-Title = JUnit
Automatic-Module-Name = junit
Implementation-Version = 4.13
Archiver-Version = Plexus Archiver
Built-By = marc
Implementation-Vendor-Id = junit
Build-Jdk = 1.6.0_65
Created-By = Apache Maven 3.1.1
Implementation-URL = http://junit.org
Manifest-Version = 1.0
Implementation-Vendor = JUnit
或者,如果你非常渴望一艘客轮:

groovy -e 'new java.net.URL("jar:file:" + new java.io.File(args[0]).getAbsolutePath() + "!/").openConnection().getManifest().getMainAttributes().each { k, v -> println("$k = $v") }' ~/.m2/repository/junit/junit/4.13/junit-4.13.jar

jar文件只是zip文件。我知道这个线程很旧,但对谁来说可能会有问题:根据手册,使用-p或-c进行解压缩将以二进制形式打印输出。如果您需要以某种方式解析此输出(例如到关联数组),则应该强制使用-aa参数进行文本表示,以使其正确。我添加了一个带有Groovy脚本的答案,该脚本使用Java的API获取并打印呈现的键/值对,以及一个bash友好的一行程序来调用它。