命令行

**命令行(cli/command-line)通常指操作系统或一些程序中的命令式管理器,它通常显示地通过控制台(console)/终端(terminal)**方便用户控制。 在 Julia 中,可以通过 cmd 对命令进行管理,通过 ARGS 常量获取调用时的参数。

打开系统命令行

如果您提出了这个问题,那么多半是在使用 windows。在高版本中,可以同时按下 windows 徽标键与 R 调出“运行”窗口。这里您可以直接输入目标程序名(如 julia 调出 REPL,但应预先设置好默认路径),或是输入 cmd 调出传统控制台,powershell 调出高级控制台。

执行程序

对于一个可执行程序或是批处理脚本,只需在命令行里直接输入它的文件名即可执行它。 当然,执行一个文件时,命令行并不会把所有目录下的文件都找一遍。环境变量 PATH 描述了命令行搜索路径的范围,命令行会在 PATH 中的路径寻找目标文件。 对于 Windows 系统,当前目录也在命令行的默认搜索范围内。例如 Windows 系统中,输入 hello 命令就可以执行当前目录下的 hello.exe。但是在 PowerShell 中,PowerShell 默认不会从当前目录寻找可执行文件(这与在 Unix 的行为一致),因而在 PowerShell 中需要使用相对路径或绝对路径调用当前目录下的可执行文件。

自动补全

补全是 Shell 提供的基本功能之一,主要用于减少命令行使用中的输入量和 typo 概率。 一般情况下,使用补全的快捷键一般是 Tab,按下后 Shell 会根据已输入的字符补全信息。 以下是常见 Shell 的补全能力:
Shell补全能力(补全范围)
cmd文件路径
PowerShell文件路径、PATH 中的命令名、内建命令名、函数名、命令参数,支持模糊匹配,自动纠错
Bash文件路径、PATH 中的命令名、内建命令名、函数名、命令参数
Zsh文件路径、PATH 中的命令名、内建命令名、函数名、命令参数,支持模糊匹配,自动纠错和建议
Fish文件路径、PATH 中的命令名、内建命令名、函数名、命令参数,支持模糊匹配,补全时可显示参数功能,自动纠错和建议
Note
  • PowerShell 的部分功能需要 PSReadline Module 载入或者位于 PowerShell ISE 中

  • Bash 的补全功能一般需要一个名为 bash-completions 的包才能获得完整功能,部分软件的补全文件由软件包自带

  • Zsh 完整的补全功能需要配合用户预定义的文件(一般随 Zsh 包或对应软件包安装)

  • Fish 在默认配置下提供良好完整的补全功能,但仍有部分官方未覆盖到的软件的补全文件由软件自行提供

帮助文档

一般来说,命令行下的程序都附有“帮助”,Windows 下一般使用 command /? 或者 command -? 获取,Unix-like(例如 Linux) 上一般使用 command --help 或者 command -h 获取。(但是 BSD 下的“帮助”往往过分简略而难以使用) 此外,在 Unix-like 系统上,还有可通过 man command 获取的“手册”(manual),相比“帮助”一般更为详细。

管道

假设我们现在有两个程序 A 和 B,都用标准输入输出,如何让 A 的输出重定向到 B 的输入?

一种方式是重定向:先把 A 的输出重定向到一个临时文件,在把 B 的输入重定向到这个临时文件上,但这个方法很低效,不仅需要创建新的文件,磁盘 IO 的操作也可能成为瓶颈,而且两个程序不能同时运行,必须等 A 跑完了才能开始跑 B。有没有更好的方法?

有,那就是「管道」

Julia 提供了 Pipe 方便操作;在命令行中,使用 A | B。 这会在内存创建一个管道,然后两个程序被同时启动。程序 A 每次要输出被重定向到这个管道中,而这个管道本身不会存储数据(其实有一个很小的缓冲区)。在 B 读取之前,A 的输出操作会被阻塞,等到 B 把数据读入以后,A 的输出才能继续进行。这样优美地解决了上述的问题,没有磁盘 IO 操作,两份代码同时运行,也没有额外消耗很多的内存储存中间结果

命名管道

有时候我们不只是要把一个程序的输出重定向到另一个的输入。例如将 A 的输出重定向到 B 的输入,B 的输出重定向到 A 的输出,这个时候用上文提到的普通管道就无能为力了。而重定向到文件,又无法让两个程序同时运行。这个时候就需要一个长得像文件的管道——命名管道。 在 Unix 系统中,可以使用 mkfifo my_pipe 创建命名为 my_pipe 的管道。 这个时候使用 ls 命令列出当前目录下的文件,会发现多了一个 my_pipe| 文件。这就创建了一个命名管道,文件名后的 | 代表这是一个管道文件。然后就可以像文件的重定向一样向这个管道中读写了。 通过命名管道,我们可以这样让两个程序交互:

$ mkfifo input output
$ ./checker > input < output # 这里一定要把 > input 写在前面,不然 shell 会先打开 output 管道,而这个管道现在并没有东西,会阻塞 checker 的运行。
$ ./my_code < input > output
使用完后,可以像普通文件一样用 rm 命令删除命名管道。

控制台

许多控制台支持:

  • 使用键盘上的上下箭头获取之前/之后(若有)的输入记录

  • 使用键盘上的左右箭头改变光标位置,从中间插入输入

  • 通常在输入完后使用回车提交

参阅

  • 1

    https://oi-wiki.org/tools/cmd/