在学习编程的过程中,我们无法避免地要去配置各种各样的环境变量等等,然后打开终端测试等等。但是有的同学即使是学习了很长一段时间的编程,也还是对命令行、环境变量等等这些概念一头雾水。然而,这些基本概念事实上是贯穿于我们整个开发和学习过程中的,因此非常有必要去了解。
如果之前大家学过其它编程语言例如C语言等等,相信也接触过命令行这个东西,在大家的印象中,命令行差不多就是一个“黑框框”。
正是因为这个黑框框,看起来是那么的“简陋”,甚至是那么的抽象,导致很多同学会有点“抵触”它,觉得在每天使用视窗的时代,我们并不需要它,它是原始而复杂的。
在命令行中,不可避免地我们要去通过输入命令的方式,来完成一些操作,而不是像平时一样点点鼠标就行了,这导致一些同学更是“敬而远之”。
但事实上,即使是现在图形化越来越好的情况下,命令行仍然是不可或缺的一部分。
如果说你是一个电脑日常使用者,那么即使是不了解命令行也可以很好地使用电脑。但如果你是一个开发者,那么命令行也是必须要接触的一个方面了。
之前在b站上面刷到这样一个视频:
事实上这并非是危言耸听,作为开发者,一些基础的层面我们确实需要去了解一下,而不能仅仅关注代码这么写。
当然,这是不是说明我们要专门去深入学习一下cmd怎么用呢?那倒也不必,但至少得有所了解和会基本使用,以及一些基本概念等等,否则在后续开发也是会踩坑的。
事实上,我们几乎在初学任何一门语言例如Java,C语言,Python等等,在初学时编写出来的程序都是命令行程序。
比如说对于学习Java的同学,在最开始配置JDK环境变量的时候,通常会测试编译一个程序,就是通过命令行操作,并且其中System.out.println
方法打印消息,也是输出到命令行窗口。
当然了,大多数编程语言也提供了编写图形化界面的API可供我们编写出带有窗口的图形化界面应用程序,例如Java的swing包等等。不过我觉得在开始学习一个编程语言的时候,是完全没有必要去学习图形化编程的。并且Java也不太适合做图形化程序,如果大家对编写图形用户界面程序感兴趣的话,建议去学习一下C#语言,C#语言编写一个图形用户界面程序比Java方便太多了。
1,认识命令行和图形化界面
(1) 命令行(CLI):使用复杂但是功能强大
事实上最先开始的电脑操作系统都是没有现在的图形化操作界面的,几十年前,电脑普遍使用的是MS-DOS操作系统,开机之后只有输入命令的黑色背景和白色字符的界面。也因此在之前电脑的学习成本是非常高的,每天必须背下来很多的命令才能很好地操作电脑,进入到某个文件夹、创建文件夹等,都需要通过命令来实现。
因此,命令行界面(command-line interface,CLI)是在图形用户界面得到普及之前使用最为广泛的用户界面,它通常不支持鼠标,用户通过键盘输入指令,计算机接收到指令后,予以执行,也有人称之为字符用户界面(CUI)。
(2) 图形用户界面(GUI):便捷易用且直观
图形用户界面是一种人与计算机通信的界面显示格式,允许用户使用鼠标等输入设备操纵屏幕上的图标或菜单选项,以选择命令、调用文件、启动程序或执行其它一些日常任务。与通过键盘输入文本或字符命令来完成例行任务的字符界面相比,图形用户界面有许多优点。
现在家喻户晓的Windows操作系统,就是一个强大的图形操作系统。我们平时所使用的大多数软件,都是有图形用户界面的。
事实上,图形界面的产生是为了简化大家使用计算机,可以说,图形界面对很多命令行操作进行了封装。
但是,现在无论是什么操作系统,都保留了命令行这个功能,这是因为:
- 命令行界面较图形用户界面大大地节约了计算机系统的资源
- 命令行可以实现更加灵活的功能
- 更好地控制操作系统
- 比起GUI,命令行可以更好地实现自动化
- ...
所以说,GUI和CLI并非是互相替代的关系,而是互补的关系。
在我们编程开发的学习过程中,我们接触到的很多工具,都是命令行程序:
- 版本控制工具Git
- 项目构建工具Maven
- npm包管理器(前端开发)
- Java的编译器javac
- ...
如果说完全不会命令行,那么接触配置这些工具的时候,会遇到很多难题。
2,命令行的基本使用
按下win + r
键打开运行,输入cmd
就可以打开这个黑黑的命令行窗口了!当然,直接在任务栏的搜索中输入cmd
也可以,这个就是系统自带的命令提示符工具。
我们在里面可以执行一些常用命令,例如大家可以通过ping
命令查看连接一个网站的延迟以检测这个网站的速度和自己的网络情况:
ping cn.bing.com 复制代码
输入上述命令回车,即可得到下列结果:
(1) 命令的基本格式
通过上述命令,我们发现命令的格式事实上很简单,几乎所有命令都是以下格式:
命令 参数1 参数2 ...
上述ping
命令中,有一个参数就是你要测试延迟的网址,有些命令没有参数,而有些命令有多个参数,多个参数用空格隔开,大多数命令的参数是可以自由组合的,有的参数是必须的,而有的可以省略。。。
至于参数的顺序、有无、格式、意义等等,这就取决于这个命令本身的设计及其作用了!
大多数命令都会提供帮助选项,一般在命令后面带上参数--help
或者-h
等等,这取决于不同的命令,例如显示java
命令的用法:
如果大家一开始接触命令,可能会有点迷糊,不知道这些命令怎么用,因此我们可以通过查看命令帮助,或者是通过上网查阅等等来学会命令的使用。
当然,我们通常在学习一个命令行开发工具的时候,也会去学习其基本的命令行用法,网上的教程也很多。
其实,我们很多人排斥使用命令行是因为我们对使用命令行没有信心,认为很难像电影里那些黑客那样非常熟练地使用命令行。而当我们尝试去学习时,也总是会看到包含大量命令说明的书籍或教程,一下子我们可能就畏惧了。其实,对于初学者来说,你根本不需要去看那些书,因为它们大部分是为系统管理员写的。而对于一个程序员,你只需要从熟悉那些最常用的基本命令开始,比如
ls
,cd
,pwd
,cp
等,并尝试反复使用它,当你习惯并适应使用这些命令以后,便可以更进一步,尝试写一些自动化脚本来帮助你完成一些工作。
(2) 当前路径
无论是程序开发,还是使用命令行,我们必须要明确一个概念:当前路径。
当前路径也称作运行路径,为什么要有运行路径这个东西呢?原因事实上很简单,因为很多程序会涉及到文件读写的操作,在指定的是相对路径的时候,程序就会以运行路径为基础去查找。
每个命令或者程序运行时,都会有它的运行路径。
运行路径通常会显示在命令行窗口中当前行的最前面:
可见我们直接打开命令行的时候,运行路径默认是我们的用户文件夹(家目录) 。
在Windows下有一个命令是dir
,可以显示当前路径下的所有文件,我们来试一下,直接在cmd中输入dir
回车执行即可:
我们并没有给dir
命令指定要列出文件的位置,但是它仍然输出了结果,很显然dir
输出了当前路径下的文件列表。
同样地,一些命令需要我们指定一个文件路径去执行,例如删除文件del
命令,需要给定要删除的文件路径作为参数。
del 要删除的文件路径
这个路径可以是绝对路径,比如我要删除C:\Users\swsk33\Downloads\a.txt
这个文件:
del "C:\Users\swsk33\Downloads\a.txt"
那如果你输入的是相对路径会怎么样呢?例如下面这个:
del test.txt
很显然,会删除我们当前路径下的text.txt文件。
假设我们的当前路径是C:\Users\swsk33
,那么上述命令就会把我们传入的相对路径test.txt
和当前路径拼接以找到这个文件的位置,这样删除的就是C:\Users\swsk33\test.txt
。
命令的参数可以用英文双引号包围,也可以不用。尤其是当参数是文件路径的时候,就最好用英文双引号包围了,因为一些路径中间是带空格的,不用双引号包围会导致命令解析参数的时候,将其拆成多个参数。使用双引号包围就表示这是一个参数。
到此大家也明白了绝对路径和相对路径这个概念:
- 绝对路径:一个文件的完整路径,通常是以根路径或者盘符作为起点,例如
C:\Users\swsk33\test.txt
- 相对路径:相对于某个文件或者运行路径的路径,在程序设计或者是命令执行的时候,输入相对路径时,都是相对于运行路径来寻找文件的
我们还是用del
命令举例,假设我们的运行路径是C:\Users\swsk33
:
del a.txt
删除当前路径下的a.txt
文件,拼接成绝对路径就是删除C:\Users\swsk33\a.txt
del .\a.txt
等效于上一条命令,.\
就表示当前路径del ..\a.txt
删除当前路径的上一级目录的a.txt
文件,拼接成绝对路径就是删除C:\Users\a.txt
,..\
表示上一级目录del ..\..\a.txt
删除当前路径的上一级的上一级目录的a.txt
文件,拼接成绝对路径就是删除C:\a.txt
,可见可以把多个..\
连起来表示多个上级目录del b\a.txt
删除当前路径中b
文件夹中的a.txt
文件,拼接成绝对路径就是删除C:\Users\swsk33\b\a.txt
,等效于命令del .\b\a.txt
可见路径的表示就是这么简单,不同的命令虽然参数格式和意义不一样,但是路径的表示形式、当前路径的概念永远是不变的。
在Windows操作系统中,目录用\
进行分隔,而Linux操作系统中,路径是用/
分隔的,./
和../
用于在Linux操作系统中表示当前路径和上一级路径。
可见绝对路径虽然精准,但是很长,并且只适用于自己的电脑,相对路径就非常的简短,因此大多数时候使用命令传参都传入相对路径作为参数(谁愿意输这么长的命令呢),既然是相对路径,那当然需要一个“参照物”,因此在运行命令的时候,运行路径就是参照。
就如上面我们执行del a.txt
命令,传入的是相对路径a.txt
,那a.txt
在哪里呢?这时del
命令就知道去当前路径下找到a.txt
,这就是当前路径的存在意义。
可见有了运行路径,我们就可以传入更加简短的相对路径作为参数,程序或者命令也可以利用运行路径和相对路径拼接以找到对应的文件。
(3) 切换当前路径
在命令行窗口中,通过cd
命令即可实现切换当前路径。
假设我要切换当前路径到C:\Program Files
目录下,则执行:
cd C:\Program Files
对比切换前后,发现当前路径就改变了。
我们当前路径是在C盘下的,如果说要切换的路径位于其它盘,则还需要在cd
后面加上/d
参数,例如切换到D:\Program Files
,如下:
cd /d D:\Program Files
这样才能切换成功。
(4) 批处理脚本
顾名思义,批处理就是批量处理一些任务的脚本。事实上,批处理脚本就是把一些要执行的命令写在脚本中,然后鼠标点击运行脚本,就会依次运行这些命令。
批处理文件通常以bat
或者cmd
作为扩展名,相信大家平时也见过。
假设我们现在要完成一系列操作:
- 先进入
D:\dir
目录 - 删除
f.txt
文件 - 打印“已完成删除”消息
我们就可以用文本文档或者文本文件器写以下内容:
@echo off cd"D:\dir"del f.txt echo 已完成删除
保存为一个扩展名为bat
或者cmd
的文件,然后双击它,就会从上至下依次执行我们的命令了!可见批处理脚本就是把要执行的多条命令按照顺序写在一起,点击运行脚本时,这些命令就会依次执行。
注意第一行@echo off
表示关闭回显,这个写脚本通常就会习惯性地加在第一行,至于具体意义大家可以上网查。
那有的同学就问了,运行脚本的时候,里面命令的运行路径是什么?
这就要分两种情况讨论了:
- 鼠标双击脚本:运行路径就是脚本所在路径
- 在命令行中调用脚本:运行路径就是命令行的运行路径
比如说写了一个脚本名为a.bat
,放在D:\bat
目录下,那么在命令行中调用意思是:打开命令行窗口,在其中执行:
start"D:\bat\a.bat"
start
命令可以用于在命令行中打开一个应用程序或者是脚本。
打开命令行窗口时,命令行的运行路径是C:\Users\swsk33
,那么这个脚本中的命令运行路径就也是C:\Users\swsk33
。
当然,在脚本中使用cd
命令也可以切换当前路径,上述删除文件脚本就是先切换到了文件所在目录下。
这里只是简单地介绍一下批处理脚本,大家感兴趣可以上网查阅更多关于批处理的写法。
3,环境变量
(1) 认识环境变量以及Path
变量
我们如果说是学习Java的话,最先开始安装JDK的时候,就需要配置环境变量,大家如果是以后接触别的开发工具基本上也需要配置环境变量。那环境变量究竟是什么?为什么我们要配置这个东西?
先来看一下百度百科对环境变量的定义:
环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数,如:临时文件夹位置和系统文件夹位置等。
环境变量是在操作系统中一个具有特定名字的对象,它包含了一个或者多个应用程序所将使用到的信息。例如Windows和DOS操作系统中的path环境变量,当要求系统运行一个程序而没有告诉它程序所在的完整路径时,系统除了在当前目录下面寻找此程序外,还应到path中指定的路径去找。用户通过设置环境变量,来更好的运行进程。
可见环境变量是存在于系统中的一些变量,相当于对一些常用的值起一个名字,我们引用这个名字即可得到其值。系统中通常有多个环境变量,而每个环境变量的作用也是不一样的。
不过我们还是先来认识一下今天的主角:环境变量Path
。
事实上,我们在命令行执行的命令,都是一个个命令行程序。系统自带的命令,通常在C:\Windows\System32
目录下可以找到。例如我们前面执行的ping
命令,就可以找到:
我们执行命令,事实上就是调用了这些命令行程序,并且这些程序都可以接收并解析参数。
细心的同学发现我们Java程序的主函数中有个参数Stirng[] args
,包括C语言的main
函数中也可以带上int argc
和char *argv[]
这两个参数,这些就是用于接收命令行参数的。
所以说,我们学会编程之后,也可以自己写一个命令了!
当然了,你输入一个命令的时候,计算机是怎么找到这个命令对应的程序在哪里的呢?事实上,这就是环境变量Path
起了作用。
当你执行一个命令的时候,命令行会依次在下列路径中寻找这个命令程序:
- 当前目录
- 环境变量
Path
中指定的路径
比如我们输入了ping
命令,那么命令行就会去上述路径寻找ping.exe
并调用它。
这时相信大家明白了配置JDK环境变量的意义所在:让系统能够找到我们的java
命令和javac
命令。
假设不配置环境变量,你执行java
命令时,会报错如下:
很显然,系统没有找到java
命令程序的所在位置。
因此,之前的环境变量配置,就是把java
命令等加入到环境变量Path
中,这样系统才能找到它。
(2) Windows设定和查看环境变量的方法
在Windows操作系统下,右击此电脑 - 属性 - 系统高级设置:
点击环境变量按钮,即可进入环境变量的设定页面:
可见环境变量分为两种:
- 用户环境变量(上部分):当前用户的环境变量,这里的环境变量只对当前用户生效
- 系统环境变量(下部分):系统环境变量,对所有用户生效
用户环境变量的优先级会大于系统环境变量。不过我们通常设定系统环境变量即可!
可以点击新建按钮增加一个自定义的环境变量,选中某个环境变量点击编辑按钮以编辑其值。当然不建议在没有目的的情况下随意编辑其值。
(3) 变量的引用
我们发现已经设定了许许多多环境变量,在Windows中,我们可以用%变量名%
的形式来引用它们,也就是用两个%
包围变量名,即可以引用这个变量。
可以在设定环境变量值的时候或者在命令行中,引用环境变量。
上述有一个系统环境变量OS
,值为Windows_NT
,我们在命令行中可以输出它的值试试看:
echo %OS%
当然还可以这样:
echo 我的操作系统是:%OS%
可见是很简单的。
变量名不区分大小写。
(4) Path
环境变量
Path
环境变量可以说是最重要的环境变量之一,上面也讲述过了它的作用:执行命令时,系统除了在当前目录下寻找命令可执行文件之外,就会去Path
变量中记录的路径查找。
我们先打开Path
变量看一下:
可见Path
变量是多个路径的集合。点击新建或者浏览按钮可以加一个路径,选中一个路径点击删除可以删除它,上移和下移可以调整优先级,编辑可以修改其中某个路径值。
通常刚刚安装好系统之后,Path
变量会默认有以下路径:
%SystemRoot%
%SystemRoot%\system32
%SystemRoot%\System32\Wbem
%SystemRoot%\System32\OpenSSH
%SystemRoot%\System32\WindowsPowerShell\v1.0
上面的%SystemRoot%
也是变量引用格式,其值为C:\Windows
。这也可见为什么系统自带的命令我们无需像JDK一样配置环境变量就可以执行,因为Path
环境变量里面一开始就自带了系统路径。
到这里大家还有一个疑惑:别的环境变量为什么值都是一个字符串,而Path
变量是一个列表呢?
事实上Path
环境变量的值也是一个字符串,只不过它比较特殊,在Windows设置中为了方便用户操作,就将其显示成列表形式了!
上述截图是我电脑的Path
环境变量,它的实际值是这个样子的:
%SystemRoot%;%SystemRoot%\system32;%SystemRoot%\System32\Wbem;%SystemRoot%\System32\OpenSSH;%SystemRoot%\System32\WindowsPowerShell\v1.0;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;D:\Program Files\Redis;C:\Program Files\dotnet;C:\Program Files\Git\cmd;D:\Program Files\Maven\bin;D:\Program Files\MySQL\bin;D:\Program Files\TDM-GCC\bin;D:\Program Files\nodejs;D:\Program Files\命令行程序;%PYTHON_HOME%;%PYTHON_HOME%\Scripts;%JAVA_HOME%\bin;
可见Path
变量中记录的多个路径,是用英文分号;
隔开的。事实上点击“编辑文本”按钮,就可以以字符串形式编辑Path
变量了。
当然,以列表形式编辑更加方便,但是大家还是有必要了解一下Path
变量值的格式。
在Windows7及其以下操作系统中,我们只能以字符串方式编辑
Path
环境变量,这样的话我们添加路径时需要注意是否已经手动用分号隔开了路径。
并且,可见在Path
变量中,也可以引用其它环境变量。
比如说我们之前配置的JDK环境变量,我们先配置了JAVA_HOME
变量,其值就是JDK的安装路径。我的JDK安装在C:\Program Files\Zulu\zulu-17
,所以其值就是这个。
然后在Path
中,我们增加了%JAVA_HOME%\bin
这个路径,引用了上面的JAVA_HOME
,因此其值实际上是C:\Program Files\Zulu\zulu-17\bin
,而java
及其相关的命令都在这个目录下:
这样,就把JDK命令所在目录加入到了Path
环境变量中,使得我们可以通过命令行调用它们。
但有的同学会问了:为什么非要先配置一个JAVA_HOME
变量呢?直接在Path
中加入JDK安装路径\bin
不就好了吗?
事实上这样也可以达到效果,在命令行中仍然可以调用到java
及其相关命令。之所以先要配置JAVA_HOME
,除了因为是官方给出的规范之外,还有以下原因:
- 很多Java相关的开发工具都需要调用
java
及其相关命令,而这些工具都会先去找JAVA_HOME
这个变量以引用java
- 便于我们切换
java
版本,比如说我的电脑上安装了多个版本的Java,我们只需修改JAVA_HOME
中的值为想要的版本的Java所在路径,即可达到切换版本的效果 - ...
所以说,配置JDK环境变量的时候,还是按照规范来比较好。
可见,Path
环境变量可以指定一些命令所在目录,除了要配置的Java命令之外,其它命令行程序如果说我们要通过命令行调用,也可以自己将其所在路径加入到Path
环境变量,就可以在命令行调用它了!
如果说不把一个命令行程序的所在位置加入Path
环境变量能不能调用它呢?当然可以。
比如说在我的D:\Program Files\命令行程序
目录下有aria2c.exe
这个命令行程序,如果说在不配置环境变量的情况下直接调用它,则要通过命令行程序所在的绝对路径调用:
"D:\Program Files\命令行程序\aria2c.exe"-h
可见是非常麻烦的,如果每个命令都要写绝对路径调用,那不太麻烦了!可见Path
的作用是多么的重要。
现在要调用aria2c
这个命令,我们就可以先把其所在目录D:\Program Files\命令行程序
加入到Path
中。
大家还发现,命令行程序都是可执行程序,以exe
作为扩展名,然而输命令的时候并不需要带上.exe
,确实是这样的,当你输入一个命令的时候,系统会去当前路径或者Path
中寻找这个命令对应的可执行文件,可执行文件不限于.exe
、.com
、.bat
、.cmd
等等,可以是可执行文件也可以是脚本等等。
通俗地讲,比如我们执行命令aria2c
,那么系统会去对应路径寻找aria2c.exe
、aria2c.com
、aria2c.bat
、aria2c.cmd
等等。找到了其中一个就停止寻找并调用它。
当然了,调用命令的时候,带上扩展名也是可行的,比如说:
aria2c.exe -h
等效于aria2c -h
。
除此之外,我们还可以用where
命令查看某个命令对应的程序在哪个地方,例如:
where java where npm
4,总结
到这里,相信大家已经学会了命令行的基本使用,以及一些关于命令行的常用概念,以及Path
环境变量的作用等等。相信到这里,大家以后在博客或者是教程中看到以下描述,就不会挠头了:
- 在
xx
路径下执行命令xxx
(通过cd
命令进入到xx
路径然后执行xxx
命令) - 将
xx
路径加入到Path
环境变量(在环境变量设置中找到Path
,编辑,加入xx
路径)
大家明白了Path
环境变量的意义,相信大家以后再遇到xxx不是内部或外部命令
这样的报错,就一眼能看出来是因为没有把对应的命令行程序所在目录加入到Path
环境变量中去而导致的问题了!
不仅仅是JDK,以后还有很多开发工具,都是要通过命令行调用的,我们也需要配置环境变量,当然了方法都是一样的,把它们所在位置加入到Path
即可。
其余大多数命令行程序,无需先设定类似
JAVA_HOME
的变量,只需直接将它们可执行文件所在目录加入到Path
中即可。
以后的开发,我们几乎每天要接触到命令行这个东西,而系统自带的cmd
并不是那么的好用,因此我推荐大家可以使用其它功能更高级的命令行终端软件:
- Tabby
- Cmder
- Windows Terminal
非常推荐大家使用Tabby这个软件,有着非常强大的功能和美观的界面:
并且,其它很多命令行终端,可以在右键菜单中直接打开,这样省的我们每天使用cd
命令切换当前目录,非常麻烦。
比如说在C:\Users\swsk33\Downloads
文件夹中右键打开Tabby:
那么开启后终端的当前路径就是C:\Users\swsk33\Downloads
:
上图~
代表用户目录,我的即为C:\Users\swsk33
。
可见非常方便,以后要在某个目录下执行命令,无需cd
到那个目录下,直接在那个目录下右键打开终端即可。大多数终端软件都有这个功能。
大家可以参考这个博客学习Tabby的配置和使用:传送门
除此之外,配置环境变量除了在系统高级设置中,还可以使用这款开源的环境变量设置工具,它可以一键检测Java和Python的安装位置并一键配置:传送门
事实上,在Linux系统中也有环境变量这个概念,并且Linux也有Path
这个变量,作用和Windows是一样的,大家今天知道了Windows中环境变量的意义,以后在Linux中也能很快学会了,Linux环境变量的配置方式有所不同,不过也很简单,大家上网查查就会了。