我发现我自己和我的同学们总是记不住很多东西指令,尤其是tar和jar指令,要用的时分都是面向Google编程。
归档指令-tar
tar是一个古老的Linux指令,了解根本功用可对付80%的备份需求,了解更细节的用法则可称心如意。
根本功用
根本功用便是 归档和提取。
归档和提取
tar根本功用便是将多个文件和目录归档到一个归档文件里,并且今后能够从归档文件里提取出本来的文件内容。 如下:
- 当咱们将多个文件和目录归档到一个归档文件时,需求运用-c功用,
tar -cf archive.tar foo bar
将foo bar归档到archive.tar里边。 - 当咱们从归档文件里提取出本来的文件内容时,需求运用-x功用,
tar -xf archive.tar
提取archive.tar里的文件到当时目录。
咱们能够发现根本功用后面都运用了f选项,去掉f选项将不能正常作业,这是为什么呢?
因为在tar的规划里边-f 后面接归档的文件姓名,比方这里便是archive.tar;不论是归档还是提取,这个f后面都是接归档的文件姓名。
咱们需求知道归档文件的内容才好提取文件到目录(按需,否则可能存在安全的问题),那tar也供给了查询归档文件内容的功用。
Table列出
t(table)表明列出包里边的内容,-v显现功用动作详细的履行进程,如下:
# tar tvf archive.tar
-rwxr-xr-x root/root 106 2021-11-15 21:48 hello
-rw-r--r-- root/root 0 2021-11-15 23:18 hello2
tar的运用风格比较古老,
tar tvf archive.tar
和tar -tvf archive.tar
等价。
更多功用-细节&高效
tar还供给很多细节功用:
- 追加内容
- 提取部分内容
- 创立进程,能够排除文件
- 紧缩宽和紧缩
- -j 支撑bg2紧缩格式
- -z 支撑gz紧缩
增加上额外功用后,整个tar的功用图变得生动起来了:
- -r 追加,运用
tar -rvf archive.tar /zhangsan
能够将 /zhangsan目录加到archive.tar 里边 - 还能够只提取某一个文件,并且指定提取到目录,这里
tar -xf archive.tar file1 -C /tmp/
提取file1到指定目录/tmp/ - -p 后面不跟参数,归档时文件权限保留
- -z和-j都表明归档文件是紧缩文件,只是格式不相同
- 关于tar.gz 格式的归档文件,归档和紧缩时都加-z,tar.bzip相同
-
tar -cvzf backup.tar.gz ...
创立tar.gz的归档文件,关于这样的文件,t和x操作的时分能够不加z选项。
Java打包-jar包
jar和tar十分的类似,jar(Java Archive)能够将多个源码、资源等文件打包并紧缩到一个归档文件中。也支撑更新、检查、提取。 更重要的是,jar包能够依照各种java程序运转的约好去打包。
根本功用
- 根本功用也是c x t,这几个选项根本和tar的对应的用法一模相同
- u 更新文件,相当于tar的r
- v:显现详细进程
- f:指明jar文件的姓名
详细如下图所示
能够看出,功用上jar和tar十分的类似,甚至在提取和检查时,直接用tar指令也是能够的。
但是JAR 创立包的时分会默许加上一个 META-INF/MANIFEST.MF,如下演示:
# jar cvf doc.jar A.md
# jar tf doc.jar
META-INF/
META-INF/MANIFEST.MF
A.md
# jar xf doc.jar META-INF/MANIFEST.MF
# cat META-INF/MANIFEST.MF
Manifest-Version: 1.0
Created-By: 12.0.2 (Oracle Corporation)
也能够运用unzip -p控制台检查:
# unzip -p doc.jar META-INF/MANIFEST.MF
Manifest-Version: 1.0
Created-By: 12.0.2 (Oracle Corporation)
jar包运转:清单文件
那什么是META-INF/MANIFEST.MF? 为什么要加META-INF/MANIFEST.MF?
即使什么都不做,检查MANIFEST.MF文件的内容能够知道它记录着jar包的版别信息、创立时刻。 最重要的是java将jar包作为可运转的程序,指定程序入口,便能够直接java -jar的方式运转程序了。
谚语说:如果你把事情整理的整整有条,用的时分就不用去找了。
如下图所示:
- -e选项:能够指定main方法所在的类,清单文件中就会多一行Main-Class: com.ywz.Main
- -m选项:创立自己的清单文件 写入Main-Class: com.ywz.Main ;
演示: 只用了简略的一个java类:
//$ cat com/ywz/Main.java
package com.ywz;
public class Main{
public static void main(String[] args) {
System.out.println("Hello,My Reader!");
}
}
操作演示:
$ javac com/ywz/Main.java#编译
$ jar cvf example.jar com/ywz/Main.class
已增加清单
正在增加: com/ywz/Main.class(输入 = 426) (输出 = 298)(紧缩了 30%)
$ jar tf example.jar #list jar包的内容
META-INF/
META-INF/MANIFEST.MF
com/ywz/Main.class
$ unzip -p example.jar META-INF/MANIFEST.MF #根本信息
Manifest-Version: 1.0
Created-By: 12.0.2 (Oracle Corporation)
##cp指定Class-Path是example.jar ,java程序的候默许class loader会从 example.jar来查找class
$ java -cp example.jar com.ywz.Main #指定jar包资源的运转,com/ywz/Main和com.ywz.Main都能够
Hello,My Reader!
##不指定cp的时分便是当时途径
$ java com/ywz/Main #当时途径的运转,com/ywz/Main和com.ywz.Main都能够
Hello,My Reader!
## -e 指定Main-Class: com.ywz.Main
$ jar cvfe example.jar com.ywz.Main com/ywz/Main.class
已增加清单
正在增加: com/ywz/Main.class(输入 = 426) (输出 = 298)(紧缩了 30%)
$ unzip -p example.jar META-INF/MANIFEST.MF #验证加了Main-Class
Manifest-Version: 1.0
Created-By: 12.0.2 (Oracle Corporation)
Main-Class: com.ywz.Main
$ java -jar example.jar #-jar运转
Hello,My Reader!
## -m 指定Main-Class: com.ywz.Main
$ echo "Main-Class: com.ywz.Main" > example_manifest.txt
$ jar cvfm example.jar example_manifest.txt com/ywz/Main.class
已增加清单
正在增加: com/ywz/Main.class(输入 = 426) (输出 = 298)(紧缩了 30%)
$ unzip -p example.jar META-INF/MANIFEST.MF #验证加了Main-Class
Manifest-Version: 1.0
Main-Class: com.ywz.Main
Created-By: 12.0.2 (Oracle Corporation)
$ java -jar example.jar #-jar运转
Hello,My Reader!
-
javac编译java文件
-
cp指定Class-Path是example.jar ,java程序的候默许class loader会从 example.jar来查找class,所以运转的时分需求知道哪个类是main类,需求指定,因而运转的指令写法还比较麻烦。
-
-e或-m 指定Main-Class: com.ywz.Main,打包好便能够直接java -jar example.jar运转
maven打包
上面描绘的是jar的初级功用,现在一般都运用更高档的东西maven来协助构建和打包java程序。 程序目录结构:
$ tree
.
├── pom.xml
├── src
│ └── main
│ └── java
│ └── Main.java
$ cat pom.xml
因为代码简略,就没有上传github源码了
- Main.java和上面描绘的相同
- pom文件装备:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.ywz</groupId>
<artifactId>test</artifactId>
<version>1.0</version>
<properties>
<argLine>-Dfile.encoding=UTF-8</argLine>
<java.version>1.8</java.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>com.ywz.Main</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>
- 运用插件maven-jar-plugin,指定archive manifest的mainClass是com.ywz.Main
- 生成的jar包和之前用jar指令生成的差不多,运转也是相同的作用。如下:
$ mvn package
$ tar tf target/test-1.0.jar #只多了META-INF/maven的信息
META-INF/
META-INF/MANIFEST.MF
com/
com/ywz/
com/ywz/Main.class
META-INF/maven/
META-INF/maven/com.ywz/
META-INF/maven/com.ywz/test/
META-INF/maven/com.ywz/test/pom.xml
META-INF/maven/com.ywz/test/pom.properties
$ unzip -p target/test-1.0.jar META-INF/MANIFEST.MF #符号是被Apache Maven 3.6.1创立
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven 3.6.1
Main-Class: com.ywz.Main
$ java -jar target/test-1.0.jar#运转
Hello,My Reader!
能够看出:
- jar包里只多了META-INF/maven的信息
- META-INF/MANIFEST.MF符号是被Apache Maven 3.6.1创立的.
清楚jar的用法之后,咱们就不会被maven各种各样的插件功用遮挡视线,而且发现jar打包和插件逻辑也是很简略的!