HOME/Articles/

命令行详解

Article Outline

命令行相关概念介绍

<!--more-->

什么是命令行

kernel: 内核负责硬件进行交互,负责CPU的调度,进程的调度以及IO相关的操作。 Shell 就是和 Kernel进行交互的。

  • 广义的命令行包括一切通过字符终端控制计算机的方式
    • windows: cmd / PowerShell / Git Bash
    • linux: sh / zsh / Terminal 等

为什么需要命令行

  • 必须用: 公司的服务器运行在linux上
  • 将工作自动化
  • 相比于GUI,命令行更容易进行开发维护(BUG更少)
  • 远程连接时,命令行占用资源远低于GUI
  • 命令行上的开发者工具更加丰富

环境变量

  • 进程(Process)
    • 进程是计算机程序运行的最小单位
    • 独占自己的内存空间和文件资源
  • 每个进程都和一组变量相绑定
    • 传递不同的环境变量可以让程序表现出不同的行为
    • CLASSPATH / GOPATH
  • 在进程的fork过程中,环境变量可以被完全继承
  • 所有的操作系统/编程语言都支持环境变量
  • 局部和全局的环境变量

进程是由其父进程启动的,linux系统开始只有一个init进程,然后init进程启动了桌面进程等其他进程。在这些进程中,父进程的环境变量会一直传递下来。

环境变量使用举例

  • 通过export / set 设置环境变量,通过echo读取环境变量
  • 从Java / Go / Python / Node.js 中都可以读取到环境变量
  • 向Docker容器传递环境变量 docker run -it Test=123 ubuntu echo $Test
  • 快速传递一个环境变量 Test=123 node index.js
  • 使用环境变量控制程序的行为

可执行程序

  • windows: exe / bat / com
  • linux: x权限(可执行权限) 如果chmod取消可执行权限就不是一个可执行程序了

当执行一句java -version的时候,去哪找这个java.exe?

  • windows:Path环境变量 + 当前目录

  • linux: PATH环境变量

  • 在脚本的第一行可以指定解释器(即shebang) 比如指定sh文件里面的语句用node来解释,那么就可以指定shebang为:#!/usr/bin/env

  • 设置别名(alias) 比如git status 设置为gst alias gst='git status'就可以在当前环境变量中使用,要想永久设定,还需要修改终端配置文件

参数

  • Unix参数的约定(Java并不遵守) 即-后面跟一个字符,几个字符可以合并 --后面跟一个单词

  • 参数中包含空格或者字符串 对于命令后面传递的参数里面有空格的情况,如echo i love Shell,可以使用引号将其包起来让执行程序认为是一个参数而不是多个参数。

    • 单引号 单引号时是原样输出作为参数的
    • 双引号 但是双引号时,会对参数做解析,如果有环境变量之类的字符串,会解析为环境变量的值然后再作为参数

举个例子: 假设我们现在要传递3个参数给一个Java程序,第一个为空字符串,第二个为一个空格,第三个为一个号,即可以这么传`java targetClass '' ' ' ''`

  • 参数的展开 我们执行ls *.java时,其实传递的参数为当前目录的所有java文件,命令行会把通配符偷偷进行转换展开。 ls *.java就等价于ls 1.java 2.java

输入输出

  • 标准输入 stdin
  • 标准输出 stdout
  • 标准错误 stderr
  • 输出的重定向
    • 覆盖文件 覆盖文件即可以直接使用>,例如java targetClass > output.txt
    • 追加文件 如果要追加在目标文件后面而不删除原有内容的话,则可以使用>>进行追加
    • 改变流向 标准输出为1,标准错误为2,如果想重定向标准错误的话,可以直接写java targetClass 2> output.txt,如果想都重定向的话,则可以先将2重定向到1再重定向到其他地方java targetClass > output.txt 2>&1

      流的写法是从右向左的

    • /dev/null(垃圾桶,如果想丢弃输出,即可指向到这个目录) 比如java Main 2> /dev/null即丢弃了stderr

linux常用命令

  • cd: change directory
  • ls/ll/ls -alth
  • mv: move
  • cp /cp -r: copy
  • rm/rm -r/rm -rf: remove
  • echo
  • export
  • git系操作: git pull/push/add/commit/...
  • mkdir/mkdir -p: make directory
  • pwd: print working directory
  • cat: concatenate and print files
  • vi: vim

Java与命令行

  • Java世界里的一切工具都是在拼接命令行
  • 可以使用命令行编译并且运行Java程序 在编辑和运行java程序时,可以通过-classpath(简写为-cp)来进行指定所有的目录,多个目录用:分隔(windows下为;
  • Java程序中的环境变量与系统属性详解 JVM中内置了一些类似于环境变量的属性,称为system property,只在JVM中存在。环境变量在java中可以通过System.getenv()获得,系统变量可以通过System.getProperty()获得 比如常用的获取System.getProperty("user.dir");, System.getProperty("java.version");

使用-D指令,例如Java -DtestProperty=123 Main可以传递系统变量, 注意-D要写在前面

  • 使用Java程序启动新的进程 通过Java中的ProcessBuilder来fork子进程: 例如现在要起一个子进程来,将子进程的输出重定向到一个目标文件:
    ProcessBuilder pb = new ProcessBuilder("sh", "run.sh"); // 新创进程,指定可执行程序
    pb.directory(workDir); // File workDir 即指定进程工作目录
    Map<String, String> envs = pb.enviroment();
    envs.put("AAA", "123"); // 设置环境变量AAA=123
    // pb.inheritIO(); 将子进程的输出定向到和当前进程一样的输出
    pb.redirectOutput(outputFile); // 将子进程的输出重定向到目标文件
    pb.start().waitFor(); // 开始允许子进程并且等待子进程允许结束