标签 CLI 下的文章

当你开始使用 Linux 并关注关于 Linux 的网站和论坛时,你会经常遇到诸如 GUI、CLI 等术语,有时还会遇到 TUI。

这一章的 Linux 黑话解释简要解释了这些术语,以便你作为一个(新的)Linux 用户在使用这些缩写词时能够更好地理解上下文。

说实话,像 GUI、CLI 或 TUI 这样的术语并不是 Linux 的专属术语。这些都是通用的计算术语,你会发现在非 Linux 的讨论中也会用到它们。

GUI - 图形用户界面 Graphical User Interface

这可能是你在这里最常遇到的词汇。这是因为我们专注于桌面 Linux 用户,并试图涵盖易于使用的图形化方法和应用程序。

GUI 应用程序(或图形应用程序)基本上是指任何可以与你的鼠标、触摸板或触摸屏交互的东西。有了图标和其他视觉概念,你可以使用鼠标指针来访问功能。

GIMP:一个用于照片编辑的GUI应用程序

在 Linux 上,桌面环境为你提供了与系统交互的图形界面,然后,你可以使用 GUI 应用程序,如 GIMP,VLC、Firefox、LibreOffice、文件管理器等来完成各种任务。

GUI 使普通用户的计算机使用变得更加容易,否则它将仍然是一个极客专用区。

CLI - 命令行界面 Command Line Interface

CLI 基本上是一个接受输入来执行某种功能的命令行程序。基本上,任何可以在终端中通过命令使用的应用程序都属于这一类。

apt-cache 是一个 CLI 工具,用于在基于 Debian 的系统上与 APT 缓存交互

早期的电脑与操作系统交互没有鼠标,你必须使用命令与机器互动。

如果你认为这都算困难,那你应该知道,早期的计算机甚至没有一个屏幕可以看到正在输入的东西,他们用实体的纸质打印机看到他们的输入命令。我从来没有用过这样的电脑,也没有在现实生活中看到过。我用过的最接近的东西是学习期间的单片机套件。

现在的 CLI 还有用吗?当然有。命令总是有它的好处,特别是当你处理操作系统的核心功能和配置时,比如设置防火墙、管理网络甚至包管理

你可能会有一个基于 GUI 的应用程序来完成同样的任务,但命令可以让你更精细地访问这些功能。在一些情况下,你会发现 GUI 应用程序也会用命令(在它们的代码中使用)与操作系统交互。

Handbrake GUI 应用程序在底层使用 FFMPEG CLI 工具

许多流行的 GUI 应用程序往往是基于 CLI 工具的。以Handbrake 为例。这是一个流行的开源媒体转换器,它底层使用的是 FFMPEG 命令行工具。

很明显,使用命令行工具没有图形工具那么简单。不要担心。除非你有特殊需要,否则你应该可以用图形化的方式使用 Linux 系统。然而,了解基本的 Linux 命令会有很大的帮助。

TUI - 终端用户界面 Terminal User Interface (也称为 基于文本的用户界面 Text-based User Interface

这是三者中最不常见的名词。TUI 基本上部分是 GUI,部分是 CLI。糊涂了吗?让我为你解释一下。

你已经知道,早期的计算机使用 CLI。在实际的 GUI 出现之前,基于文本的用户界面在终端中提供了一种非常基本的图形交互。你会有更多的视觉效果,也可以使用鼠标和键盘与应用程序进行交互。

终端中的 nnn 文件浏览器

TUI 是基于文本的用户界面或终端用户界面的缩写。“基于文本”这个说法主要是因为你在屏幕上有一堆文本,而“终端用户界面”的说法是因为它们只在终端中使用。

TUI 的应用虽然不是那么常见,但你还是有一些的。基于终端的 Web 浏览器是 TUI 程序的好例子。基于终端的游戏也属于这一类。

CMUS 是基于终端的音乐播放器

当你在 Ubuntu 中安装多媒体编解码器时,你可能会遇到 TUI,你必须接受 EULA 或做出选择。

TUI 应用程序不像 GUI 应用程序那样用户友好,它们经常会有学习曲线,但它们比命令行工具更容易使用一些。

最后……

TUI 应用程序通常也被认为是 CLI 应用程序,因为它们被限制在终端上。在我看来,你是否认为它们与 CLI 不同,这取决于你。

我希望你喜欢这篇 Linux 黑话解释。如果你对这个系列的主题有什么建议,请在评论中告诉我,我将在以后尽量涵盖它们。


via: https://itsfoss.com/gui-cli-tui/

作者:Abhishek Prakash 选题:lujun9972 译者:wxy 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

借鉴 C 语言的历史,学习如何用 Python 编写有用的 CLI 程序。

本文的目标很简单:帮助新的 Python 开发者了解一些关于命令行接口(CLI)的历史和术语,并探讨如何在 Python 中编写这些有用的程序。

最初……

首先,从 Unix 的角度谈谈命令行界面设计。

Unix 是一种计算机操作系统,也是 Linux 和 macOS(以及许多其他操作系统)的祖先。在图形用户界面之前,用户通过命令行提示符与计算机进行交互(想想如今的 Bash 环境)。在 Unix 下开发这些程序的主要语言是 C),它的功能非常强大。

因此,我们至少应该了解 C 程序的基础知识。

假设你没有读过上面那个链接的内容,C 程序的基本架构是一个叫做 main 的函数,它的签名是这样的。

   int main(int argc, char **argv)
   {
   ...
   }

对于 Python 程序员来说,这应该不会显得太奇怪。C 函数首先有一个返回类型、一个函数名,然后是括号内的类型化参数。最后,函数的主体位于大括号之间。函数名 main运行时链接器(构造和运行程序的程序)如何决定从哪里开始执行你的程序。如果你写了一个 C 程序,而它没有包含一个名为 main 的函数,它将什么也做不了。伤心。

函数参数变量 argcargv 共同描述了程序被调用时用户在命令行输入的字符串列表。在典型的 Unix 命名传统中,argc 的意思是“ 参数计数 argument count ”,argv 的意思是“ 参数向量 argument vector ”。向量听起来比列表更酷,而 argl 听起来就像一个要勒死的求救声。我们是 Unix 系统的程序员,我们不求救。我们让其他人哭着求救。

再进一步

$ ./myprog foo bar -x baz

如果 myprog 是用 C 语言实现的,则 argc 的值是 5,而 argv 是一个有五个条目的字符指针数组。(不要担心,如果这听起来过于技术,那换句话说,这是一个由五个字符串组成的列表。)向量中的第一个条目 argv[0] 是程序的名称。argv 的其余部分包含参数。

   argv[0] == "./myprog"
   argv[1] == "foo"
   argv[2] == "bar"
   argv[3] == "-x"
   argv[4] == "baz"
   
   /* 注:不是有效的 C 代码 */

在 C 语言中,你有很多方法来处理 argv 中的字符串。你可以手动地循环处理数组 argv,并根据程序的需要解释每个字符串。这相对来说比较简单,但会导致程序的接口大相径庭,因为不同的程序员对什么是“好”有不同的想法。

include <stdio.h>

/* 一个打印 argv 内容的简单 C 程序。 */

int main(int argc, char **argv) {
    int i;
   
    for(i=0; i<argc; i++)
      printf("%s\n", argv[i]);
}

早期对命令行标准化的尝试

命令行武器库中的下一个武器是一个叫做 getoptC 标准库函数。这个函数允许程序员解析开关,即前面带破折号的参数(比如 -x),并且可以选择将后续参数与它们的开关配对。想想 /bin/ls -alSh 这样的命令调用,getopt 就是最初用来解析该参数串的函数。使用 getopt 使命令行的解析变得相当简单,并改善了用户体验(UX)。

include <stdio.h>
#include <getopt.h>

#define OPTSTR "b:f:"

extern char *optarg;

int main(int argc, char **argv) {
    int opt;
    char *bar = NULL;
    char *foo = NULL;
   
    while((opt=getopt(argc, argv, OPTSTR)) != EOF)
       switch(opt) {
          case 'b':
              bar = optarg;
              break;
          case 'f':
              foo = optarg;
              break;
          case 'h':
          default':
              fprintf(stderr, "Huh? try again.");
              exit(-1);
              /* NOTREACHED */
       }
    printf("%s\n", foo ? foo : "Empty foo");
    printf("%s\n", bar ? bar : "Empty bar");
}

就个人而言,我希望 Python 有开关,但这永远、永远不会发生

GNU 时代

GNU 项目出现了,并为他们实现的传统 Unix 命令行工具引入了更长的格式参数,比如--file-format foo。当然,我们这些 Unix 程序员很讨厌这样,因为打字太麻烦了,但是就像我们这些旧时代的恐龙一样,我们输了,因为用户喜欢更长的选项。我从来没有写过任何使用 GNU 风格选项解析的代码,所以这里没有代码示例。

GNU 风格的参数也接受像 -f foo 这样的短名,也必须支持。所有这些选择都给程序员带来了更多的工作量,因为他们只想知道用户要求的是什么,然后继续进行下去。但用户得到了更一致的用户体验:长格式选项、短格式选项和自动生成的帮助,使用户不必再试图阅读臭名昭著的难以解析的手册页面(参见 ps 这个特别糟糕的例子)。

但我们正在讨论 Python?

你现在已经接触了足够多(太多?)的命令行的历史,对如何用我们最喜欢的语言来编写 CLI 有了一些背景知识。Python 在命令行解析方面给出了类似的几个选择:自己解析, 自给自足 batteries-included 的方式,以及大量的第三方方式。你选择哪一种取决于你的特定情况和需求。

首先,自己解析

你可以从 sys 模块中获取程序的参数。

import sys

if __name__ == '__main__':
   for value in sys.argv:
       print(value)

自给自足

在 Python 标准库中已经有几个参数解析模块的实现:getoptoptparse,以及最近的 argparseargparse 允许程序员为用户提供一致的、有帮助的用户体验,但就像它的 GNU 前辈一样,它需要程序员做大量的工作和“模板代码”才能使它“奏效”。

from argparse import ArgumentParser

if __name__ == "__main__":

   argparser = ArgumentParser(description='My Cool Program')
   argparser.add_argument("--foo", "-f", help="A user supplied foo")
   argparser.add_argument("--bar", "-b", help="A user supplied bar")
   
   results = argparser.parse_args()
   print(results.foo, results.bar)

好处是当用户调用 --help 时,有自动生成的帮助。但是 自给自足 batteries included 的优势呢?有时,你的项目情况决定了你对第三方库的访问是有限的,或者说是没有,你不得不用 Python 标准库来“凑合”。

CLI 的现代方法

然后是 ClickClick 框架使用装饰器的方式来构建命令行解析。突然间,写一个丰富的命令行界面变得有趣而简单。在装饰器的酷炫和未来感的使用下,很多复杂的东西都消失了,用户惊叹于自动支持关键字补完以及上下文帮助。所有这些都比以前的解决方案写的代码更少。任何时候,只要你能写更少的代码,还能把事情做好,就是一种胜利。而我们都想要胜利。

import click

@click.command()
@click.option("-f", "--foo", default="foo", help="User supplied foo.")
@click.option("-b", "--bar", default="bar", help="User supplied bar.")
def echo(foo, bar):
    """My Cool Program
   
    It does stuff. Here is the documentation for it.
    """
    print(foo, bar)
   
if __name__ == "__main__":
    echo()

你可以在 @click.option 装饰器中看到一些与 argparse 相同的模板代码。但是创建和管理参数分析器的“工作”已经被抽象化了。现在,命令行参数被解析,而值被赋给函数参数,从而函数 echo魔法般地调用。

Click 接口中添加参数就像在堆栈中添加另一个装饰符并将新的参数添加到函数定义中一样简单。

但是,等等,还有更多!

Typer 建立在 Click 之上,是一个更新的 CLI 框架,它结合了 Click 的功能和现代 Python 类型提示。使用 Click 的缺点之一是必须在函数中添加一堆装饰符。CLI 参数必须在两个地方指定:装饰符和函数参数列表。Typer 免去你造轮子 去写 CLI 规范,让代码更容易阅读和维护。

import typer

cli = typer.Typer()

@cli.command()
def echo(foo: str = "foo", bar: str = "bar"):
    """My Cool Program
   
    It does stuff. Here is the documentation for it.
    """
    print(foo, bar)
   
if __name__ == "__main__":
    cli()

是时候开始写一些代码了

哪种方法是正确的?这取决于你的用例。你是在写一个只有你才会使用的快速而粗略的脚本吗?直接使用 sys.argv 然后继续编码。你需要更强大的命令行解析吗?也许 argparse 就够了。你是否有很多子命令和复杂的选项,你的团队是否会每天使用它?现在你一定要考虑一下 ClickTyper。作为一个程序员的乐趣之一就是魔改出替代实现,看看哪一个最适合你。

最后,在 Python 中有很多用于解析命令行参数的第三方软件包。我只介绍了我喜欢或使用过的那些。你喜欢和/或使用不同的包是完全可以的,也是我们所期望的。我的建议是先从这些包开始,然后看看你最终的结果。

去写一些很酷的东西吧。


via: https://opensource.com/article/20/6/c-python-cli

作者:Erik O'Shaughnessy 选题:lujun9972 译者:wxy 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

让我们来看几个精心设计的 CLI 程序,以及如何解决一些可发现性问题。

在本文中,我会指出命令行界面的 可发现性 discoverability 缺点以及克服这些问题的几种方法。

我喜欢命令行。我第一次接触命令行是在 1997 的 DOS 6.2 上。我学习了各种命令的语法,并展示了如何在目录中列出隐藏的文件(attrib)。我会每次仔细检查命令中的每个字符。 当我犯了一个错误,我会从头开始重新输入命令。直到有一天,有人向我展示了如何使用向上和向下箭头按键遍历命令行历史,我被震惊了。

后来当我接触到 Linux 时,让我感到惊喜的是,上下箭头保留了它们遍历历史记录的能力。我仍然很仔细地打字,但是现在,我了解如何盲打,并且我能打的很快,每分钟可以达到 55 个单词的速度。接着有人向我展示了 tab 补完,再一次改变了我的生活。

在 GUI 应用程序中,菜单、工具提示和图标用于向用户展示功能。而命令行缺乏这种能力,但是有办法克服这个问题。在深入解决方案之前,我会来看看几个有问题的 CLI 程序:

1、 MySQL

首先让我们看看我们所钟爱的 MySQL REPL。我经常发现自己在输入 SELECT * FROM 然后按 Tab 的习惯。MySQL 会询问我是否想看到所有的 871 种可能性。我的数据库中绝对没有 871 张表。如果我选择 yes,它会显示一堆 SQL 关键字、表、函数等。(LCTT 译注:REPL —— Read-Eval-Print Loop,交互式开发环境)

MySQL gif

2、 Python

我们来看另一个例子,标准的 Python REPL。我开始输入命令,然后习惯按 Tab 键。瞧,插入了一个 Tab 字符,考虑到 Tab 在 Python 源代码中没有特定作用,这是一个问题。

 title=

好的用户体验

让我看下设计良好的 CLI 程序以及它们是如何克服这些可发现性问题的。

自动补全: bpython

Bpython 是对 Python REPL 的一个很好的替代。当我运行 bpython 并开始输入时,建议会立即出现。我没用通过特殊的键盘绑定触发它,甚至没有按下 Tab 键。

 title=

当我出于习惯按下 Tab 键时,它会用列表中的第一个建议补全。这是给 CLI 设计带来可发现性性的一个很好的例子。

bpython 的另一个方面是可以展示模块和函数的文档。当我输入一个函数的名字时,它会显示这个函数附带的签名以及文档字符串。这是一个多么令人难以置信的周到设计啊。

上下文感知补全:mycli

mycli 是默认的 MySQL 客户端的现代替代品。这个工具对 MySQL 来说就像 bpython 之于标准 Python REPL 一样。mycli 将在你输入时自动补全关键字、表名、列和函数。

补全建议是上下文相关的。例如,在 SELECT * FROM 之后,只有来自当前数据库的表才会列出,而不是所有可能的关键字。

 title=

模糊搜索和在线帮助: pgcli

如果您正在寻找 PostgreSQL 版本的 mycli,请看看 pgcli。 与 mycli 一样,它提供了上下文感知的自动补全。菜单中的项目使用模糊搜索缩小范围。模糊搜索允许用户输入整体字符串中的任意子字符串来尝试找到正确的匹配项。

 title=

pgcli 和 mycli 在其 CLI 中都实现了这个功能。斜杠命令的文档也作为补全菜单的一部分展示。

可发现性: fish

在传统的 Unix shell(Bash、zsh 等)中,有一种搜索历史记录的方法。此搜索模式由 Ctrl-R 触发。当再次调用你上周运行过的命令时,例如 sshdocker,这是一个令人难以置信的有用的工具。 一旦你知道这个功能,你会发现自己经常会使用它。

如果这个功能是如此有用,那为什么不每次都搜索呢?这正是 fish shell 所做的。一旦你开始输入命令,fish 将开始建议与历史记录类似的命令。然后,你可以按右箭头键接受该建议。

命令行规矩

我已经回顾了一些解决可发现性的问题的创新方法,但也有一些基本的命令行功能应该作为每个 REPL 所实现基础功能的一部分:

  • 确保 REPL 有可通过箭头键调用的历史记录。确保会话之间的历史持续存在。
  • 提供在编辑器中编辑命令的方法。不管你的补全是多么棒,有时用户只需要一个编辑器来制作完美的命令来删除生产环境中所有的表。
  • 使用分页器(pager)来管道输出。不要让用户滚动他们的终端。哦,要为分页器设置个合理的默认值。(记得添加选项来处理颜色代码。)
  • 提供一种通过 Ctrl-R 界面或者 fish 式的自动搜索来搜索历史记录的方法。

总结

在第 2 节中,我将来看看 Python 中使你能够实现这些技术的特定库。同时,请查看其中一些精心设计的命令行应用程序:

  • bpythonptpython:具有自动补全支持的 Python REPL。
  • http-prompt:交互式 HTTP 客户端。
  • mycli:MySQL、MariaDB 和 Percona 的命令行界面,具有自动补全和语法高亮。
  • pgcli:具有自动补全和语法高亮,是对 psql 的替代工具。
  • wharfee:用于管理 Docker 容器的 shell。

了解更多: Amjith Ramanujam 在 5 月 20 日在波特兰俄勒冈州举办的 PyCon US 2017 上的谈话“神奇的命令行工具”。


作者简介:

Amjith Ramanujam - Amjith Ramanujam 是 pgcli 和 mycli 的创始人。人们认为它们很酷,他表示笑纳赞誉。他喜欢用 Python、Javascript 和 C 编程。他喜欢编写简单易懂的代码,它们有时甚至会成功。


via: https://opensource.com/article/17/5/4-terminal-apps

作者:Amjith Ramanujam 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

提问:我运行的是Ubuntu桌面,但是我希望启动后临时进入命令行。有什么简便的方法可以启动进入终端?

Linux桌面自带了一个显示管理器(比如:GDM、KDM、LightDM),它们可以让计算机启动自动进入一个基于GUI的登录环境。然而,如果你要直接启动进入终端怎么办? 比如,你在排查桌面相关的问题或者想要运行一个不需要GUI的应用程序。

注意虽然你可以通过按下Ctrl+Alt+F1到F6临时从桌面GUI切换到虚拟终端。然而,在这种情况下你的桌面GUI仍在后台运行,这不同于纯文本模式启动。

在Ubuntu或者Debian桌面中,你可以通过传递合适的内核参数在启动时启动文本模式。

启动临时进入命令行

如果你想要禁止桌面GUI并临时进入一次文本模式,你可以使用GRUB菜单。

首先,打开你的电脑。当你看到初始的GRUB菜单时,按下‘e’。

接着会进入下一屏,这里你可以修改内核启动选项。向下滚动到以“linux”开始的行,这里就是内核参数的列表。删除参数列表中的“quiet”和“splash”。在参数列表中添加“text”。

升级的内核选项列表看上去像这样。按下Ctrl+x继续启动。这会以详细模式启动控制台一次(LCTT译注:由于没有保存修改,所以下次重启还会进入 GUI)。

永久启动进入命令行

如果你想要永久启动进入命令行,你需要更新定义了内核启动参数GRUB设置

在文本编辑器中打开默认的GRUB配置文件。

$ sudo vi /etc/default/grub 

查找以GRUB\_CMDLINE\_LINUX\_DEFAULT开头的行,并用“#”注释这行。这会禁止初始屏幕,而启动详细模式(也就是说显示详细的的启动过程)。

更改GRUBCMDLINELINUX="" 成:

GRUB_CMDLINE_LINUX="text"

接下来取消“#GRUB\_TERMINAL=console”的注释。

更新后的GRUB配置看上去像下面这样。

最后,使用update-grub命令来基于这些更改重新生成/boot下的GRUB2配置文件。

$ sudo update-grub 

这时,你的桌面应该可以从GUI启动切换到控制台启动了。可以通过重启验证。


via: http://ask.xmodulo.com/boot-into-command-line-ubuntu-debian.html

译者:geekpi 校对:wxy

本文由 LCTT 原创翻译,Linux中国 荣誉推出