学习C/C++或者Fortran这样经典的静态编程语言,甚至还有Python这样流行的动态语言,都难免要用到“命令行”这个东西。对于很多刚入门的、习惯了基于鼠标操作的图形用户界面的小白们,那个黑色框框可谓是既有逼格又充满陌生感。本文基于Windows操作系统,为新手小白介绍一番对命令行的基本理解方式,以及计算机中的一个重要基础概念——文件路径

  • 命令行是什么?
  • 命令解释方式
  • 工作目录与文件路径
  • 命令行的具体用法

命令行是什么?

命令行 (command line) 是各种操作系统(包括Windows、macOS、Linux)为用户提供的一种相对原始的交互界面,也经常被称作shell (壳子) 或terminal (终端)。它通过读取用户输入的命令,来执行一个或一组对应的操作。在图形用户界面 (GUI) 出现以前,这是系统基本的交互方式。时至今日,这项功能仍在各大操作系统中以不同形式保留着。

以Windows为例,系统预装了一个经典的命令解释程序cmd (C:WindowsSystem32cmd.exe) 和一个新式的PowerShell

还有一个更新款但没有预安装的PowerShell Core(这玩意儿不止支持Windows,可前往 https:// github.com/PowerShell/P owerShell/releases 下载你需要的版本)。

通过快捷键Win+S或者点击任务栏上的搜索框/按钮,输入cmd或者powershell就能直接找到这两个程序了。以cmd为例,启动后就是如下界面,




python windows脚本输入路径中有空格怎么处理_c# 指定打开某个路径下的CMD


最上方标题栏可能是中文字样“命令提示符”也可能是程序路径“C:WindowsSystem32cmd.exe”。窗口中首先打印出的是系统版本信息,然后单起一行的类似C:UsersZeng>的提示符和它后面闪烁的光标,就是提示你输入命令的地方

命令解释方式

无论是cmd还是PowerShell,严格来讲都是所谓“命令解释程序”,它们是命令行这种交互方式/概念的具体实现。不同的解释程序在支持的命令和一些具体细节上可能会有所不同,但基本的逻辑应该无差。

首先,在你敲下回车之后,你输入在提示符之后的所有文字,将按照空格分割成一个个块 (token),用一对英文双引号括起来的部分视为一个块,不进行分割

然后第一个块,将作为要执行的命令进行解释——

  1. 如果它是系统命令,则执行相应的命令;
  2. 如果不是,将从环境变量Path列举的路径中搜索与其同名的程序,如果匹配到就执行相应的程序;
  3. 如果没匹配到,就判断它是否是一个合法的程序文件路径(可能是相对路径或者绝对路径),如果是就执行相应的程序。
  4. 如果以上匹配全部失败,命令解释程序应该就会提示你该命令或程序不存在。这一般是命令名称敲错了、或者没有添加相应的Path,又或者要执行程序的路径搞错了

无论执行的是系统命令还是某个程序,后面其他的块都会作为该命令或程序的参数传入,这些参数的合法性和作用则由相应的命令或程序来决定

系统命令:命令解释程序预定义的命令,在cmd中输入命令 help,就会显示出所有系统命令和它们的简介;PowerShell预定义的命令就更多更复杂,但大体能兼容cmd的常用系统命令。
环境变量Path:可以简单理解为系统的一个设置项,里面包含了一条条路径,作为常用程序的搜索位置。将常用程序所在的目录添加进来,就能在命令行中直接以程序名执行该程序而无需输入完整路径。
程序文件:Windows中就是后缀名.exe的文件。在命令行中如果不会引起歧义,程序文件的.exe后缀可以省略。

工作目录与文件路径

前面多次提到了“路径”这一概念,这里就有必要详解一下操作系统是如何看待系统内的诸多文件的,这是多少新手小白踩坑的地方。

基本能熟练操作电脑 (Windows) 的人,必然知道系统里有很多的“盘”(C、D、E等等),每个盘下面可以有很多“文件夹”,里面可以放更多文件夹和我们的文件。对于一个具体的文件或文件夹,我们把从“此电脑”开始访问到它所需点击的所有盘符和文件夹按照特定方式连接起来,就构成了它的路径


python windows脚本输入路径中有空格怎么处理_c 路径 空格 参数_02


上图给出了一个例子,为了看清文件路径的真面目,我们在红框标记的地址栏再单击一下,


python windows脚本输入路径中有空格怎么处理_c# 指定打开某个路径下的CMD_03


这时规范的文件路径显现出来。盘符用英文字母加英文冒号表示,我这里就是C:,它一定出现在最前面;盘符和诸文件夹用反斜杠分隔,这也就意味着文件夹内部是不能出现的(事实上/:*?"<>|等特殊符号也都不能出现在文件夹或文件名中,它们有特殊作用)。还有几个点需要特别注意——

  • 文件路径中是允许空格的(上面的最后一级文件夹AIDA64 Reports中就包含空格),而上面提到过命令解释程序会用空格分割不同的块,这就意味着如果需要在命令行中使用带空格的路径(无论是作为要执行的程序还是程序的参数),必须使用一对双引号"将它括起来

“空格分割”这种方式不仅在命令解释中,在系统和很多程序底层机制中都广泛存在,所以很多特殊的程序(比如编译器)不宜被放在含空格的路径下。

  • Windows的文件路径中不区分大小写!尽管文件资源管理器会在形式上记住你建立文件夹或文件时使用的大小写,但实际使用时你写成大小写都是无所谓的。
  • 文件路径可以以文件夹或者文件收尾。文件夹末尾可以再跟一个反斜杠显式表明它是个文件夹,也可以省略末尾的;文件一般来讲都有扩展名(文件名中最后一个.和它之后的部分),文件资源管理器可能不显示已知类型文件的扩展名,但你心里得清楚它的存在。

上面的例子里文件扩展名就是隐藏的,可以按如下方式显示出来,建议不熟悉不同类型文件扩展名的、或者电脑里流氓软件多甚至还有病毒的,把扩展名显示出来比较好,毕竟文件图标和类型标识都是可以被篡改的。


python windows脚本输入路径中有空格怎么处理_c# 指定打开某个路径下的CMD_04


  • 文件资源管理器地址栏里显示的路径都是当前文件夹的,要获取其中某个文件的路径,请把完整的文件名加在后面,并用与前面分隔。比如上面那个文件夹的路径就是地址栏中的
C:UsersZengDocumentsAIDA64 Reports


而那个文件的完整路径则为


C:UsersZengDocumentsAIDA64 ReportsReport.htm


介绍完文件路径的基本概念,下一个重要概念就是相对路径,与此对应,之前介绍的就是绝对路径。而相对路径的使用,显然是要依赖于一个“基础路径”(不然它“相对”谁呢),这就引出了工作目录的概念。

上面启动cmd后,我们说到C:UsersZeng>是你输入命令的提示符。了解了文件路径之后,你会发现这>前面的部分就是一个合法的文件夹路径。这个路径,就是我们当前的工作目录。就好像你打开了系统中相应的文件夹一样,我们可以直接访问这个目录下的文件和子文件夹。

这里的 Zeng是我的用户名,你的应该是其他名字。

Windows中,绝对路径由盘符(比如C:)引导,而相对路径,则直接从当前目录下的某个文件夹或者文件开始,到你的目标文件夹或文件为止。就以cmd的默认启动目录为例(这个目录下的文件夹大都比较特殊,这里看到的都只是被汉化显示了,其实都是英文文件夹),假设我们要用相对路径表示那个“文档”文件夹,直接使用Documents即可;如果你还记得上面那个Report.htm文件的位置,它则可以用DocumentsAIDA64 ReportsReport.htm表示。这就更加方便。


python windows脚本输入路径中有空格怎么处理_c 路径 空格 参数_05


有时,相对路径也可以以.开头,显式地表明路径从当前目录开始;也可以以n个连续的..开头,表示从上n级父目录开始

命令行的具体用法

使用命令行,实质是使用一些没有图形界面的命令或者程序。上面其实介绍过最简单的help命令了,这里再举几个例子。

cd命令

cd命令是一个系统命令,作用是更改当前工作目录 (change directory)。其后可以紧跟一个合法的文件夹路径(系统中已存在且有访问权限的,绝对、相对均可,当然相对更常用),比如


python windows脚本输入路径中有空格怎么处理_c# 指定打开某个路径下的CMD_06


你可以清楚地看到工作目录已经被更改了。

注意cd命令默认状态下只能在当前驱动器(盘符)下更改目录,要想更改工作目录至其他盘,比如D盘,有两种方法。

1、增加一个/d参数,即类似下面这样


cd /d 你的目标绝对路径


2、直接利用盘符名先切换到D盘,再切到指定目录,即先输入


D:


回车后就切到了D盘根目录,再利用cd切换工作目录。

GCC编译器

假设你在C:mingw64目录下安装了GCC编译器套件,并将编译器所在路径C:mingw64bin添加到了环境变量Path中,那么这个路径下的所有程序(都是没有图形界面的)就可以再命令行中直接使用了。

比如我要编译一段C语言程序代码,代码文件位于工作目录的Experiment文件夹下,文件名为hello.c,那么它的相对路径就是Experimenthello.c,这里面没有空格,可以直接作为我们要使用的程序gcc.exe的一个参数。

gcc.exe的一个简单用法是


gcc.exe -o myhello Experimenthello.c


程序gcc.exe的后缀名一般可以省略,它接受了好几个参数。其中-o表示下一个参数是目标程序名,我这里就起为myhello;之后的参数就是要编译的代码文件,可以有好几个,我这里只有一个。程序执行成功后会在当前目录输出myhello.exe程序文件。这个程序也可以在命令行中执行。