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

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

62712 次浏览
$ unzip -q -c myarchive.jar META-INF/MANIFEST.MF
  • -q will suppress verbose output from the unzip program
  • -c will extract to stdout

Example:

$ 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

Alternatively you can use -p instead of -q -c.

-p extract files to pipe (stdout). Nothing but the file data is sent to stdout, and the files are always extracted in binary format, just as they are stored (no conversions).

use unzip:

$ unzip -q -c $JARFILE_PATH META-INF/MANIFEST.MF

that will quietly (-q) read the path META-INF/MANIFEST.MF from the jarfile (which is compressed using the zip format) to stdout (-c). You can then pipe the output to other command to answer questions like 'what is the main class for this jar:

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

(this removes all lines which don't contain the string Main-Class, then splits the line at :, keeping only the second field, the class name). Of course, either define $JARFILE_PATH appropriately or replace $JARFILE_PATH with the path to a jarfile you're interested in.

Depending on your distribution, install the unzip package. Then simply issue

unzip -p YOUR_FILE.jar META-INF/MANIFEST.MF

This will dump the contents to STDOUT.

HTH

$ tar xfO some.jar META-INF/MANIFEST.MF

x extracts and O redirects to stdout.

Note: Seem to work only in bsdtar, not GNU tar.

Others have been posting about using unzip -p and piping to grep or awk or whatever you need. While that works for most cases, it's worth noting that because of the 72 characters-per-line limit of MANIFEST.MF, you may be grepping for keys whose values are split across multiple lines and will therefore be very difficult to parse. I'd love to see a CLI tool that can actually pull a rendered value out of the file.

http://delaltctrl.blogspot.com/2009/11/manifestmf-apparently-you-are-just.html

The following Groovy script uses Java's API to parse the manifest, avoiding issues with the manifest format's weird line breaking:

#!/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") }
}

Pass JAR files as arguments:

$ 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

Or if you're desperate for a one-liner:

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