美文网首页
Java 命令行 & Maven

Java 命令行 & Maven

作者: bowen_wu | 来源:发表于2021-07-02 10:54 被阅读0次

命令行

包括一切通过字符终端控制计算机的方式

  • Kernel & Shell
  • 命令行 vs GUI

命令的要素

  • Executable => 可执行程序
  • Parameter => 参数
  • Working Directory => 工作目录
  • Environment Variable => 环境变量
ls -l
// ls -> 可执行程序
// -l 及后面所有的 -> 参数

可执行程序

  • UNIX | Linux => 可执行权限 => x 权限 =>
  • 哪里找命令 => PATH 环境变量中查找 => echo $PATH
  • 在脚本的第一行指定解释器 => shebang
    #!/usr/bin/env node    // node shebang
    

三个为一组:

  • r => read => 读 => 100
  • w => write => 写 => 010
  • x => 可执行 => 001
  • 第一组 => 当前用户权限
  • 第二组 => 本用户组
  • 第三组 => 其他用户组
chmod 756

chmod => change mode

  • 当前用户权限 -> 7 => 二进制 111 => 可读可写可执行
  • 本用户组 -> 5 => 二进制 101 => 可读可执行
  • 其他用户组 -> 二进制 110 => 可读可写
权限

参数

UNIX 参数约定

ls -a -l -t -h
// 使用一个 - 后面只能跟一个字符,这代表一个参数
// 上面四个参数可以合并,等价于
ls -alth

// 使用两个 -- 后面可以跟着一个单词
ls -a // 等价于
ls --all 
参数中包含空格 | 字符串
  • 单引号 => 作为一个整体参数传入进去,不要将其中的变量展开 => 命令行不做任何处理
  • 双引号 => 作为一个整体参数传入进去,并且将其中的变量展开 => 命令行会对里面的变量进行替换和展开

想传入进去单引号这个符号的话,可以套上一层双引号 || 使用转义

echo "'I am a boy'"
echo \'I am a boy\'

可以通过使用单引号将通配符的通配性取消,让可执行程序去解释,而不是使用命令行的传递给执行权限的值

git add * // 将所有的文件传递给 git 
git add '*' // 将 ` * ` 传递给 Git,Git 自己去解释 ` * ` 的含义

Working Directory

  • 启动命令的路径
  • 相对路径都是相对于工作目录的路径
  • 工作目录决定了程序中相对路径起始的位置

绝对路径 => 从根目录开始的路径
相对路径 => 相对于当前工作目录的路径

Environment Variable

环境变量是存在于环境中的一组键值对,会影响所有在这个环境中启动的程序的行为

  • 进程 => 进程是计算机程序运行的最小单元 => 独占自己的内存空间和文件资源
  • 每个进程都和一组变量相绑定 => 传递不同的环境变量可以让程序表现出不同的行为
  • 在进程的 fork 过程中,环境变量可以被完全继承
  • 所有的 操作系统 | 编程语言 都支持环境变量
  • 通过 export 设置环境变量,通过 echo 读取环境变量
    export AAAAA=12345
    echo $AAAAA
    
  • 容器是有点特殊的进程,它的环境变量不会受到外面环境变量的影响
  • 快速传递一个环境变量 => AAAAA=12345 source .file => file 中可以读取到环境变量 AAAAA,值为 12345,退出后这个环境变量就没有了

输入 & 输出

  • Stdin => standard input => 标准输入
  • Stdout => standard output => 标准输出
  • Stderr => standard error => 标准错误

输出重定向 >

  • > -> 将标准输出重定向到后面的文件中 => echo 'Hello World!' > temp.txt => 会覆盖
  • >> -> 将标准输出追加在后面的文件中

在进程中

  • Stdout => 进程描述符为1号输出 => 1> 等价于 >
  • Stderr => 进程描述符为2号输出 => 2> 将标准错误重定向
  • java Main > output 2>&1将标准输出和标准错误同时重定向到一个文件中

垃圾桶 /dev/null

将标准错误丢掉,丢到垃圾桶

java Main 2> /dev/null

Java & 命令行

源代码「.java文件」 --编译--> 字节码「.class文件」 --运行-->
JVM 只认识字节码「.class 文件」
jar包 => 一堆字节码的结合

javac Main.java // 编译
java Main // 运行
javac & java

System Property 系统属性

在 JVM 中有 System Property,System Property 就是 JVM 里面的环境变量

public class Main {
  public static void main(String[] args) {
    System.out.println("Hello World");
    System.out.println("args:" + java.util.Arrays.toString(args));
    System.out.println("env:" + System.getenv("AAA")); // Java 获取环境变量
    System.out.println("property:" + System.getProperty("AAA"));  // Java 获取系统属性,只在 JVM 中有效
    System.out.println("java version:" + System.getProperty("java.version"));
    System.out.println("user.dir:" + System.getProperty("user.dir"));
  }
}
javac & java
java -DAAA=456 Main 1 2 3 // -D 传递系统属性
javac -classpath commons-lang3-3.9.jar XXX.java // -classpath 可以用于传递 jar 包, -classpath 等价于 -cp
java -cp commons-lang3-3.9.jar:. XXX // 启动 java,java 运行所需要的类在 jar 包中查找同时也在当前目录下查找,并启动 XXX 类

常用命令

cd // change directory
cat // 查看一个文件的内容 concatenate and print files
pwd // print working directory
ps aux // mac 查看进程列表
docker run -it ubuntu // 使用 Linux 命令行,装 docker,之后启动 ubuntu
docker run -it -e AAAAA=12345 ubuntu // 环境变量 AAAAA 值为 12345

Maven

自动化构建工具 => 划时代的包管理

  • Convention over Configuration => 约定优于配置
  • Maven 远远不止是包管理
  • Maven 中央仓库 => 按照一定的约定存储包
  • Maven 本地仓库 => 默认位于 ~/.m2 => 下载的第三方包放在这里进行缓存

JVM 工作 => 执行一个类的字节码,这个过程中如果遇到了新的类,加载它

Classpath 类路径

-classpath | -cp => 从 Classpath 里面去寻找相关的类,之后加载它 => 每当 JVM 需要一个类时,就会在当前的 Classpath 里面找,如果碰到 jar 包,就将 jar 包解压缩,继续在解压缩的目录里面找

类的全限定类名 FQCN (目录层级)唯一确定了一个类

jar 包 == 包 => 包就是把许多类放在一起打的压缩包 => 包就是一堆类的集合

源代码中依赖的类还依赖了其他的类 => 传递性依赖

Classpath Hell 依赖地狱

  • 全限定类名是类的唯一标识
  • 当多个同名类同时出现在 Classpath 中,就是噩梦的开始

包管理

引用第三方库时,需要告知 JVM 去哪里找 => 包管理的本质 => 告诉 JVM 如何找到所需的第三方类库以及成功的解决其中的冲突问题

pom.xml => project object model

Maven 包

  • 按照约定为所有的包编号,方便检索
  • groupId + artifactId + version
  • scope => 依赖的隔离 => 在不同的代码集合中隔离第三方的依赖
    • <scope>compile</scope> => main + test 可见
    • <scope>test</scope> => test 可见,main 不可见
    • <scope>provided</scope> => 只在编译 main 代码时有效,运行时无效 => 运行的时候有其他依赖提供,防止包冲突
  • 语义化版本
  • SNAPSHOT 快照版本 => 开发使用的版本
  • 传递性依赖的自动管理 => 原则:绝对不允许最终的 classpath 出现同名不同版本的 jar 包
  • 依赖冲突的解决 => 原则:最近的胜出,如果路径相同,先声明的胜出 => 查看依赖🌲 mvn dependency:tree

包冲突

包冲突相关错误:

  1. AbstractMethodError
  2. NoClassDefFoundError
  3. ClassNotFoundException
  4. LinkageError

解决包冲突:

  1. 在项目中直接引入想要依赖的包,使得依赖的包最近
  2. 将不想依赖的包告知 maven
    // pom.xml
    <dependency>
        <groupId><groupId>
        <artifactId></artifactId>
        <version></version>
        <exclusions> // 取消 groupId 中的依赖
            <exclusion>
                <groupId></groupId>
                <artifactId></artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    

Maven 生命周期

Maven 生命周期有三种模式:default | clean | site

Maven Default Lifecycle

当运行 maven test 时,将会从开始的 validate 执行,直到 test Phase。默认情况下在这些生命周期中,什么都不会做,需要开发者通过插件 「Plugin」来指定在某个生命周期要做什么事情

Maven Plugin

  • Maven Compiler Plugin => 内置,绑定到 compile Phase => 运行到 compile Phase 执行 maven-complier-plugin 的工作,maven-compiler-plugin 的工作称为goal
  • Maven Surefire Plugin => 内置,绑定到 test Phase,测试插件 => 相关 Plugin 会自动的将 goal 绑定到相关的 Phase
  • Maven Checkstyle Plugin => 第三方插件 => 开发者显示声明该插件的 goal 用于哪个阶段 => 如果遇到两个插件同时绑定到同一个 Phase,运行顺序为声明顺序
    // 将 Maven Checkstyle Plugin 的 goal 绑定到 compile Phase
    <executions>
        <execution>
            <id>compile</id>
            <phase>compile</phase>
            <goals>
                <goal>check</goal>
            </goals>
        </execution>
    </executions>
    

知识点

  1. idea 中的 run == 编译 + 运行
  2. source => 一个 Shell 内置命令,用以在当前上下文中执行某文件中的一组命令,source 命令可简写为一个点(.)
  3. chmod => 一条在 Unix 系统中用于控制用户对文件的权限的命令(change mode)和函数。可以使用绝对模式(八进制数字模式),符号模式指定文件的权限
  4. grep => 最初用于 Unix 操作系统的命令行工具。在给出文件列表活标准输入后,grep 会对匹配一个或多个正则表达式的文本进行搜索,并值输出匹配或者不匹配的行或文本

相关文章

网友评论

      本文标题:Java 命令行 & Maven

      本文链接:https://www.haomeiwen.com/subject/jispeltx.html