命令行是你最好的朋友(译)

     1661     2月-15,14    

命令行可以是你最好的朋友但也可能是你最大的敌人,这取决于你如何使用它以及用它来干什么。 如果你和许多人一样想到命令行就头大的话,那么你来对了地方。
原文: http://net.tutsplus.com/tutorials/tools-and-tips/the-command-line-is-your-best-friend/
翻译:墨峰

命令行是你最好的朋友

命令行界面(CLI )?

是的,命令行界面就是神秘的文本流和那些奇怪的命令执行的地方,在黑色屏幕上它通常是白色(或绿色)。我认识许多很厉害的程序员,他们从来不使用 CLI;也认识一些喜欢在CLI上而不是图形界面做所有事情的初级电脑用户。 他们使用控制台应用程序来浏览网页和文件系统、阅读邮件,欣赏图片和编辑文本。他们甚至都不使用GUI来观看YouTube 上面的视频和阅读PDF。

每个人都会找到自认为最好的工作流。有的选择GUI,而有的人喜欢CLI。

一些术语

刚接触Unix/Linux的同学可能分不清终端(terminal)、控制台(console)和shell三者之间的区别。

命令行是你最好的朋友

对于我们使用者来说,这三者之间似乎没有什么不同。但事实上,用户是通过控制台连接到终端来查看计算机上运行的shell的。

这三者以前是独立的不同的硬件。控制台只有监视器和键盘,没有计算能力,通过串行接口(通常是RS-232)连接到终端。 终端类似于连接到大型机(mianfrmae)的界面,它通常具有计算能力,通过网络或是某些形式的特别链接与主机通信。终端一般也会提供系统的管理权 限,这是它常常会被放置在密闭的屋子里的原因。雇员可以通过其控制台连接到这些终端进行工作,但是不会获得大型机的管理权限。控制台和终端最终合并为单台 设备,最著名的就是现在Linux发行版中仿真的的VT终端。

shell是能够读取用户的输入,然后在屏幕上提供结果的程序。一个shell可以是基于字符的(像CLI),或是基于图形的(像Windows的 GUI)。在现代的计算机里,shell不仅仅是用户和系统之前的简单接口,它还负责管理进程,窗口,应用程序和系统的其它方面。

shell解释命令行输入的命令。用户可以把多个命令组合起来写成单个脚本。现在的shell都有各自的脚本语言,提供了执行复杂任务的能力。

大多数现代Linux发行版和Mac OSX使用被称作BASH的shell。Solaris 和 OpenIndiana shiyong默认使用KornShell(BASH的另一个变体)。请注意在本篇文章中我们主要讨论BASH。

让我们先讨论下BASH

BASH 是Bourne Agin Shell的简称,在1989年作为bourne shell 的新版本被发布,然后成为了Unix系统的默认shell。Bash由Stephen Bourne编写完成,用来替代Thompson Shel(第一个为Unix编写的shell软件)。老版的Bourne Shell在一些Unix系统上仍然存在,通常你可以使用/bin/sh找到它。然而,尽管 Bourne Shell 在新的 Linux 发行版中已经为BASH所取代,但/bin/sh 和 /bin/bash 都能被 BASH 运行。

BASH命令提示符

你总会碰到BASH的提示符。我们可以使用整个篇幅来讨论如何按照自己的习惯配置BASH的提示符。但这里我们只讨论如何一些基本的东西。

这是我的BASH提示符的样子。第一个词csaba是我的用户名,后面跟一个@,然后是我的计算机主机名,最后是当前的文件夹。 “~”代表了当前用户的用户目录, 对我来说就是/home/csaba. 命令行以$终结。在$后面输入的就是我想要shell执行的命令。

当然,这只是个简单的例子。你可以把更多的东西放到你的提示符中。让我们看看一些基本的例子。

BASH有一套特殊的变量PS1,PS2,PS3 和 PS4,用来控制在程序执行的不同阶段提示符的内容。本文只讨论PS1。你可以用下面的命令查看一下变量PS1包含的内容

首先看到的是$提示符,后面跟着命令echo $PS1 和命令的输出。在BASH中,当你想要读取变量内容时,需要把$放在变量名之前。echo命令只是简单的把它接收的参数值输出。如果参数是一个变量值,这个值就会被输出到屏幕上。

上面的输出代表了一种格式。\[\033[01;32m\]代表了绿色的颜色码,\u代表当前的主机名。\h 表示主机;\[\033[01;34m\]代表了蓝色的颜色码;\w代表了当前目录;\[\033[00m\]是将文字后续输入的文字置为高亮灰色。下面 是一个截屏可以让你更好的理解输出结果。

前面带有“\”的字符具有本身特殊的含义。另外,“\表示”会对它后面的字符(如颜色代码)进行转义。下面是从BASH的官方手册摘录的特殊字符的完整列表,你可以在BASH提示符中使用他们。

  • \a – ASCII响铃字符 (07)
  • \d – 以格式 “Weekday Month Date” 显示日期(如 “Tue May 26″)
  • \D{format} – format被传递给strftime(3)并把相应的结果插入到提示字符串中; 如果format为空则代表本地时间. 必须有括号
  • \e – ASCII转义字符 (033)
  • \h – the hostname up to the first `.’
  • \H – 主机名
  • \j – 当前Shell管理的工作数
  • \l – Shell终端设备名称的基本名
  • \n – 新行
  • \r – 回车
  • \s – shell的名称
  • \T – 12小时制当前时间,格式为 HH:MM:SS
  • \t – 24小时制当前时间,格式为 HH:MM:SS
  • \@ – 12小时制当前时间,格式为am/pm
  • \A – 24小时制当前时间,格式为am/pm
  • \u – 当前用户的名称
  • \v – shell的版本号
  • \V – BASH发行备注,版本号+补丁
  • \w – 当前工作目录,其中$HOME被缩写成”~“(使用PROMPT_DIRTRIM的值)
  • \W – 当前工作目录的basename,$HOME被缩写成”~”
  • \! – 命令的使用次数
  • \# – 命令号
  • \$ –如果UID是0则显示为#,否则为$
  • \nnn – 8进制数据nnn代表的字符
  • \[ – 开始一个非打印字符序列,这个序列可以嵌入一个终端控制序列到提示中
  • \] – 非打印字符序列结束

操作目录和文件

在命令行文件里,每个人都要导航、创建、删除,复制和移动文件系统对象并执行命令。这些对你来说可能是小菜一碟,但我们还是快速的过一遍。

一行行解释

  1. 在/home/csaba/tmp下创建一个叫做NetTuts 的目录
  2. 将当前目录新切换到新创建的目录
  3. 在当前目录下创建一个叫‘AnotherDIR’的目录
  4. 在当前目录下创建一个叫‘SecondDir’的目录
  5. 使用touch命令在“SecondDir”下创建两个空文件
  6. 将SecondDir目录切换当前目录
  7. 为了把我们当前目录放在一个堆栈上,使用命令pushd切换当前目录到~/tmp/NetTuts
  8. 列出~/tmp/NetTuts下所有的文件
  9. 使用popd命令,从栈里取到并移除顶层的目录,回到前一个目录
  10. 再把内容列出来,可以看到通过以上步骤创建的两个文件。

当然,你可以使用一个针对命令行的全能的文件管理器,称之为Midnight Commander。只要执行mc命令就可以使用它了。MC也有一个内置的颜色高亮的文本编辑器,多语言,带有智能缩进和其他的一些特色。但它不是一个成 熟的编辑器,实际上它是一个简单快速的编辑工具。你可以按F4来简单的选择任何文件,或者在编辑器中打开任何文件目录而不需要启动mc。

输入/输出

每个命令必须与命令行环境通信。命令行需要输入并提供输出。标准输入是指命令读取信息的来源,默认情况下是键盘,常被称作“stdin”。标准输出 命令的输出会被发送到的地方默认是当前的控制台,叫做“stdout”。标准Error指的是命令输出错误的地方,默认是当前控制台,常被称作 “stderr”。

到目前为止,我们只是简单的定义了可以从键盘读取命令并输出结果(包括好的和坏的)到屏幕。

在Unix(或类unix系统)中, 所有的东西都会被抽象成文件,你的键盘是文件,你的鼠标是文件,你的屏幕是文件,程序是文件, 文本是文件,等等 文件描述符是整形数用于操作系统内核引用打开的文件。所有系统至少有3个文件描述符:

  • 描述符no. 0 – 标准输入
  • 描述符 no. 1 – 标准输出.
  • 描述符 no. 2 –标准错误

重定向

Unix 系统有一个非常强大的特性:因为所有东西都是文件,你可以引用并重定向任何资源从一个位置到另一个位置。重定向操作符是 < 和 > , 分别表示stdin和stdout.因此,如果你想使用某个命令从键盘读取信息,可以这么做:

那如果想从文件读取命令你该如何做呢?可以把文件重定向到标准输入(stdin),比如

如果你想把你的命令执行结果输出到文件中,可以使用>操作符。例如,我们已经知道如何列出目录中的文件。

可以使用下面的命令把结果输出到一个文件中:

ThirdFile文件的内容是

那如果我们想导航到父目录列出它的所有文件,然后用命令把这个列表添加到存在的文件中。操作符>重定向输出到文件并且会覆盖这个文件,所以我们不能使用它。不过,我们可以使用»来把新数据附加到某个已经存在的文件中。

于是我们的文件内容就变成这样了:

输入输出重定向

现在综合我们已学到的知识,可以用不同的方式来重定向stderr,stdin和stdout。事实上,下面的命令做事情是一样的。

在第二个命令里,我们就在重定向前明确地把来源作为标准输出(>1)。请注意在1和>之间没有空格。事实上,在两个字符间放一个空格会使得1被当做ls命令一个参数,>就自动的重定向标准输出。下面的两个表达式功能一样,但和上面的功能不同。

当然,这会产生一个错误“ls: cannot access 1: No such file or directory” – 除非你真的有一个名叫1的目录名。这让我们想知道如何做下一步:重定向错误。

就像你看见的一样,第一个命令在控制台输出stderr然后重定向stdout到文件。第一个命令的结果是一个空文件和屏幕上的一条信息。第二个命令重定向错误到我们的文件。结果就是,如果在标准输出上有任何的输出,会显示的屏幕上,而错误会保存在那个文件中。

一个实际的I/O重定向例子

当你需要在命令行中搜索文件时,基本上有两种选择。第一个是locate命令。它通常(不完全是)会安装在Linux系统。updatedb命令会索引你 的文件然后locate命令会使用这个数据库来查找你的文件。事实上,它不会做实时搜索,它只是查找数据库中的索引。这就是为什么这个应用程序常常定期的 做每日更新文件数据库的原因。第二个命令叫find.这个命令执行一个实时的搜索,它比locate更精确,但明显更慢一些。

我打印了2个ls命令,这样你就可以方便的看到文件的目录结构了。第三个命令是find命令,它有一个复杂的参数系统,这里我不会详细的介绍它。但是上面 的例子演示了find最常用的用法。第一个参数.是我们搜索的目录,第二个参数是-name, 后面跟一个文件的名字。在-name参数中,我们可以使用?和*来扩展我们的搜索范围:

?代表了任何单个字符,*指的是0或多个字符。 接下来,我们会创建一个目录然后让对用户是不可读的。我们还没有讲到权限,但请别担心,很快我们就会开始。现在试试下面几个简单的命令。

我不想你有访问这个目录的权限,以便我可以在这个例子中演示find的输出内容。find试图访问所有的目录并搜索文件来匹配给定的模 式。当它不能访问某个目录时,会输出一条信息。在你有一个或两条信息的时候是没有什么关系的,但是当你作为普通用户从根文件夹搜索文件的时候,会看到很多 的错误信息,但或许只有一两条搜索结果。你不想要错过搜索结果,于是想把错误信息去掉。

我们重定向stderr到/dev/null, 这什么都没指向。任何你扔进/dev/null的东西都会简单的消失。 这是在我们不想看见错误时的通用做法。如果你想把你的搜索结果放到文件中,错误放到/dev/null, 你可以使用多个重定向。

正如你看见的,这个命令不会输入任何东西到屏幕上,因为错误和标准输出被发送到了不同的文件。但是如果你要在同一个文件中看到它们呢?你可以把stderr发送到stdout,然后发送stdout到一个文件。

重定向从右到左进行编译。因此第一个执行的是2>&1,这个会重定向stderr到stdout。然后1>./SecondDir/ThirdFile重定向标准输出(stderr已经在里面)到那个具体的文件让我们谈下权限

这里讨论的权限应用于与*nix操作系统。我不熟悉最新的Windows版本,但微软在他们的文件系统中使用了不同的概念。

用户和组

在同一台计算机上有好几个用户。事实上,一些应用程序注册自己特殊的用户,然后使用它在某个受限的环境中运行程序。每个用户可以通过它们的名字或者ID(也被称作UID)标识。

Owner

文件有自己的拥有者。默认情况下,创建文件的用户是文件的拥有者。目录只是特殊的文件,他们和普通文件一样有相同的拥有者和权限。

ls -al 命令,每个结果的拥有者被作为用户组。我们现在使用如下命令改变AnotherDir的拥有者:

chown 命令的意思是改变拥有者。它的用法比较简单:chown user:group path. 用户只能改变组的拥有者权限到某个组员。普通用户不能改变拥有者权限到某个他不能访问的用户。当然,有管理员特权的用户比如root能改变任何文件的所有 者,并设置文件的所有者为任何用户或组。 有三种类型的文件权限。

  • r – 读
  • w – 写
  • x – 执行

在第二个例子中,我们有选择性的允许读权限,去掉写权限,保留执行权限不变。 但同时,计算机的所有东西最终都会被转换成二进制流。通过使用十进制来表示二进制权限,chown命令让你可以容易设置权限。

  • rwx: 每一个bit都设置成1: 111. 十进制是7.
  • rw-: 由110代表. 十进制是6.
  • r-x: 由101代表. 十进制是5.
  • r–: 100. 十进制是4.
  • -wx: 011. 十进制是3.
  • -w-: 010. 十进制是2.
  • –x: 001. 十进制是1.
  • —: 000. 十进制是0.

chown命令接受3个数字的字符岑,每个数字在0到7之间,依次代表了对应的权限:用户、用户组和其它。

上面这个命令为所有者设置读、写和执行权限;为用户组设置读、写和非用户组权限;为其他人设置读,执行和不可写权限。

cat, sed 和 pipe

这个命令可以读取文件的内容。只需要简单的提供文件名作为参数,它就会输出文件内容到stdout。

grep

Grep 搜索一个模式然后输出匹配的行数,可以通过第三个参数指定要查找的文件。

 

增加–color选项会高亮显示结果行中的匹配到的词。

pipe

这实际上会运行cat命令。但不是把结果输出到stdout, 结果输出会被传递给grep. grep命令使用这个结果数据,然后搜索字符串“Another”。结果和我们之前的例子是一样的。

sed

这个例子把sed加到我们前面的例子中。借助于sed, 我们在cat…grep的输出中使用MyFile代替“Another File”。非常酷,不是吗?

sed 命令能够接受好几个参数。-e 参数在输入执行正则表达式。如果你不熟悉正则表达式,可以查阅相关的Nettuts+ 教程:

定义自己的命令

假如你需要频繁的执行下面的ssh命令。

这个命令太长了,为了简化它,可以自定义一个命令,比如说sshcon。 使用一个alias可以创建自定义命令。Alias语法的形式:alias shorthand=’original_comman

运行sshcon执行更复杂的ssh命令。但alias是临时的,当你注销系统时这些命令就会失效。一个可能的解决方案是在你的bashrc文件中进行配置。

.bashrc 和 .bash.profile

.bashrc 文件通常在home目录下面。它让你决定在打开控制台或登录到shell时你想执行的命令。把前面提到过的sshcon alias添加到这个文件里

把这行代码添加到文件末尾。按F2保存文件,按ESC两次关闭文件,CTRL+D可以从shell登出。打开另一个shel试试你的alias命 令。一些操作系统,比如Solaris,不需要使用~/.bashrc文件。这种情况下,可以使用~/.bash_profile.事实上,~ /.bash_profile在所有系统上都存在。

隐藏文件: 以一个点 (.) 开头的文件表明这个文件是隐藏文件。隐藏文件: 以一个点 (.) 开头的文件表明这个文件是隐藏文件。

一些网络命令

我们再来看看一些网络相关的命令。

ping

Ping命令可以方便的用来检测某个服务器是否能被访问。

它的语法非常简单:ping ip地址或名字。如果服务可访问,就会看到很多详细的回复信息。否则的话,会有错误信息描述相应的问题。

traceroute

traceroute命令显示数据包从你的计算机到目的设备的路由。

 

路由表

*nix和windows系统都有一个route命令。尽管语法上有些不同,但他们的功能基本上是一样的。这个命令可以让我们查看系统当前的路由表。如果需要的话,还可以增加或删除静态路由的

 

上面第一栏是网络连接或通信的目的地址。术语“default”的意思是没有找到匹配的项或发送到本地的路由。loopback是本地虚拟设 备,IP是127.0.0.1。这个IP总是指向本地机器,存在于所有的操作系统。第二栏是连接到达目的地使用的网关。第一行显示我的默认网关是 192.168.111.1.第二行显示了loopback,网关是localhost.第三行的网关是*,意思是访问我们自己的网络不需要网关。在这里 第三个比较有意思的是最后一栏的“lface”。”Iface”指定了与目的地通信的网口。在我的这个例子中,loopback通信在loopback接 口lo.其它的所有连接会经过eno1接口。

小贴士:如果你找不到route命令,可以试一下netstat -nr。它会产生相似的输出。

网络配置

如果你想快速看你的网络配置,只要在命令行中输入ifconfig就可以了。

 

 

这里显示了很多信息。首先,我们有两部分,分别对应一个网络适配器。我的有线网卡叫eno1。你可能会看到比如e100g0,eth0,ten0 或其它的名字。无线网络设备一般(并非绝对)以“w”开始。接口的当前状态在同一行显示。这里接口状态为UP、broadcast、running等。第 二行是IPV4的IP地址,子网掩码和广播地址。第三行除了显示的是IPV6外,其它和IPV4都相似。第四行以”ether”开始是网卡的MAC地址, 剩下的几行显示了数据传输统计信息。

当前的网络连接

还有一个有用的命令netstat.这个命令可以列出系统当前所有的网络连接,包括IP,接口和系统监听的接口。下面是我的系统上netstat命令输出的一部分。我去掉了一些不相干的信息让输出简洁点。

 

 

每行都表示了一个处于特定状态的网络链接。在这个例子中,你可以看见处于各种状态的连接,包括监听状态(看第一行,端口22,我的ssh服务),已连接,等待状态等等

结束语

hey,你已经学会了这些最常用的CLI命令!当然,这里介绍的每个命令能够做的事情比我们介绍的要多得多。希望这篇文章为你揭开了这些命令行神秘面纱的一角。感谢您的阅读!

(博客转载自:http://ux.etao.com/posts/782)

 

  • 最励志网 发表于: 2015/08/07 10:00

    好久没来了,过来踩踩
  • cheris 发表于: 2014/02/15 10:39

    测试
  • 你需要先 登录 才能发表评论.