Linux读书笔记(一)—— Shell基本命令
整理下看书时的收获,方便自己随时复习,如果有人看到的话,也算是小小的分享吧。
目前只看一本,等以后看的书多了再慢慢更新,追加或删改文章内容。
References:
- 《Linux典藏大系:Linux从入门到精通(第二版)》
命令行和 Shell 这两个概念常常是令人困惑的。在很多并不正式的场合,这两个名词代表着相同的概念,即命令解释器。然而从严格意义上讲,命令行指的是供用户输入命令的界面,其本身只是接受输入,然后把命令传递给命令解释器。后者就是 Shell。从本质上讲,Shell 是一个程序,它在用户和操作系统之间提供了一个面向行的可交互接口。用户在命令行中输入命令,运行在后台的 Shell 把命令转换成指令代码发送给操作系统。Shell 提供了很多高级特性,使得用户和操作系统间的交互变得简便和高效。
目前,在 Linux 环境下有几种不同类型的 Shell,常用的有 Bourne Again Shell (BASH)、TCSH Shell、Z-Shell 等。不同的 Shell 提供不尽相同的语法和特性,用户可以使用任何一种 Shell。在 Linux 上,BASH shell 是默认安装和使用的 Shell。本书中所有的命令都在 BASH下测试通过。当然,读者如果有兴趣,也可以尝试使用其他类型的 Shell。
Linux 默认有7个控制台,可以通过按快捷键 Ctrl+Alt+F1~F7 进入。默认情况下前 6 个控制台是命令行控制台,第 7 个则留给 X 服务器。
在 BASH 中,命令行以一个美元符号“$”作为提示符,表示用户可以输入命令了。
$
如果正在以 root 身份执行命令,那么 Shell 提示符将成为“#”,如下所示。
#
Linux的命令和文件名都是区分大小写的。
常用命令:
$ cd ##切换目录(Change working Directory)
$ ls ##列出文件和目录(List directory contents)
$ cat ##查看文件(Concatenate and print files)
$ pwd ##显示当前所在位置(Print Working Directory name)
$ tail ##查看文件结尾
$ grep ##查找文件内容(Global Regular Expression Print)
$ find ##查找文件
$ locate ##快速地定位文件
$ man ##查看帮助手册(Manual)
一些提示:
- 建议安装的时候选英文,如果选中文的话,可能有些目录名是中文,如:公共的 视频 图片 桌面等,这样通过cd命令切换目录时就比较麻烦了。
命令行补全。在输入文件名的时候,只需要输入前面几个字符,然后按下
Tab
键,Shell
会自动把文件名补全。如果以已键入的字符开头的文件不止一个,那么可以连续按下Tab
键两次,Shell
会以列表的形式给出所有以键入字符开头的文件,事实上,命令行补全也适用于所有 Linux 命令。例如输入ca
并按下Tab
键两次时,如下:linux-o5fc:/ # ca cache_check cache_restore calibrate_lens_gui cancel catman cache_dump cal call-browser case catppt cache_metadata_size calc_tickadj caller cat cache_repair calendarjanitor cameratopam catdoc
- Shell支持通配符,分别是:“*”、“?”和“[ ]”。“*”用于匹配文件名中任意长度的字符串。如:*.cpp。“?”只匹配一个字符。“[ ]”用于匹配所有出现在方括号内的字符。具体的用法可以参考网上的正则表达式教程。
- 既然在 BASH 的命令提示符前,会显示当前工作路径名,那么为什么还需要pwd这个命令呢?答案是这个特性并不是所有Shell都采用的。在 Freebsd 等操作系统中,BASH 并不自动显示当前目录。因此即便在某个版本的 Linux 中,pwd 显得完全没有必要,这并不意味着在其他版本的 UNIX/Linux系统中,pwd 也是无用的。
通常使用方式:
改变目录:
cd
输入 cd 命令,后面跟着一个路径名作为参数,就可以直接进入另外一个子目录中去。总能够用下面的命令回到自己的用户主目录。$ cd 或者 $ cd ~
在 Shell 中,“..”代表当前目录的上一级目录。而“.”则代表当前目录。
列出目录内容
ls
ls
命令是 list 的简化形式, ls 的命令选项非常之多,这里只讨论一些最常用的选项。
ls 的基本语法如下:
ls [OPTION]... [FILE]...
不带任何参数的 ls 命令,用于列出当前目录下的所有文件和子目录。
如:linux-o5fc:~ # ls .Xauthority .config .gtkrc-2.0 .xsession-errors-:0 Downloads Public bin testSymbol .bash_history .dbus .kde4 Desktop Music Templates inst-sys .cache .gnupg .local Documents Pictures Videos testA
也可以使用带-F 选项的 ls 命令。
linux-o5fc:~ # ls -F .Xauthority .config/ .gtkrc-2.0 .xsession-errors-:0 Downloads/ Public/ bin/ testSymbol@ .bash_history .dbus/ .kde4/ Desktop/ Music/ Templates/ inst-sys/ .cache/ .gnupg/ .local/ Documents/ Pictures/ Videos/ testA*
可以看到,-F 选项会在每个目录后加上/,在可执行文件后加*,在链接文件后加上@。这个选项在某些无法显示颜色的终端上会比较有用。
如果要查看隐藏文件(以.开头)的话可以加上-a参数,就会显示所有文件。
另一个常用选项是-l 选项。这个选项可以用来查看文件的各种属性。如:linux-o5fc:~ # ls -l total 44 drwxr-xr-x 1 root root 70 Dec 10 16:32 Desktop drwxr-xr-x 1 root root 0 Dec 10 16:32 Documents drwxr-xr-x 1 root root 0 Dec 10 16:32 Downloads ... -rwxrwxrwx 1 root root 0 Dec 10 20:03 testA lrwxrwxrwx 1 root root 5 Dec 10 20:05 testSymbol -> testA
ls -l
可以简写为ll
。
总共有 8 个不同的信息栏。从左至右依次表示:- 文件的权限标志;
- 文件的链接个数;
- 文件所有者的用户名;
- 该用户所在的用户组组名;
- 文件的大小;
- 最后一次被修改时的日期;
- 最后一次被修改时的时间;
- 文件名。
在 ls 命令后跟上路径名可以查看该子目录中的内容。如:
linux-o5fc:~ # ls /etc/systemd/ bootchart.conf journald.conf system timesyncd.conf user.conf coredump.conf logind.conf system.conf user
查看文本文件:
cat
和more
cat
命令用于查看文件内容(通常这是一个文本文件),后跟文件名作为参数。cat可以跟多个文件名作为参数。当然也可以使用通配符。对于程序员而言,为了调试方便,常常需要显示行号。为此,cat命令提供了-n选项,在每一行前显示行号。例如:linux-o5fc:~ # cat -n stack.h 1 /*Header file of stack */ 2 /* 2008-9-3 */ 3 4 #ifndef STACK_H 5 #define STACK_H 6 7 struct list { 8 int data; 9 struct list *next; 10 }; 11 12 struct stack { 13 int size; /* the size of the stack */ 14 struct list *top; 15 }; 16 17 typedef struct list list; 18 typedef struct stack stack; 19 20 void push( int d, stack *s ); 21 int pop( stack *s ); 22 23 int is_empty( stack *s ); 24 25 #endif
cat命令会一次将所有内容全部显示在屏幕上,这看起来是一个致命的缺陷。因为对于一个长达几页甚至几十页的文件而言,cat 显得毫无用处。为此,Linux 提供 more 命令来一页一页地显示文件内容。
linux-o5fc:~ # more /etc/shadow root:$6$ScMr7Qq4qX6X$J4JYdjpoLNK8iD0RqEphngfo46uCDvl3E4rhvtF6hIlav1POeMZdwVvsJKNuDCRcNnB9sklD0cj6eGOW3.gX9 .:17510:::::: bin:*:17366:::::: ... statd:!:17510:::::: rtkit:!:17510:::::: --More--(%86)
可以看到,more 命令会在最后显示一个百分比,表示已显示内容占整个文件的比例。按下空格键向下翻动一页,按 Enter 键向下滚动一行。按 Q 键退出。
- 阅读文件的开头和结尾:
head
和tail
另两个常用的查看文件的命令是 head 和 tail。分别用于显示文件的开头和结尾。可以使用-n 参数来指定显示的行数。
tail常用的参数除了-n
还有-f
,添加-f
参数后程序会一直监控文件,只要文件有追加内容会立刻打印出来,这在观察日志文件时非常好用。 更好的文本阅读工具:
less
less
和more
非常相似,但其功能更为强大。less改进了more命令的很多细节,并添加了许多的特性。这些特性让 less 看起来更像是一个文本编辑器——只是去掉了文本编辑功能。总体来说,less命令提提供了下面这些增强功能。- 使用光标键在文本文件中前后(甚至左右)滚屏;
- 用行号或百分比作为书签浏览文件;
- 实现复杂的检索、高亮显示等操作;
- 兼容常用的字处理程序(如 Emacs、Vim)的键盘操作;
- 阅读到文件结束时 less 命令不会退出;
- 屏幕底部的信息提示更容易控制使用,而且提供了更多的信息。
具体的使用方法可以参考编辑器“vi”的用法。就个人的使用感受来说就是剔除了编辑功能的“vi”,所以基本上我还是直接用vi。
查找文件内容:
grep
在很多时候,并不需要列出文件的全部内容,用户要做的只是找到包含某些信息的一行。这个时候,如果使用more命令一行一行去找的话,无疑是费时费力的。当文件特别大的时候,这样的做法则完全不可行了。为了在文件中寻找某些信息,可以使用 grep 命令。grep [OPTIONS] PATTERN [FILE...]
查询一个单词可以不用加引号,多个的话就要用引号了,否则程序会把后面的关键词当成文件(grep支持多文件查找)。grep支持正则表达式。
linux-o5fc:~ # grep "struct list" stack.h struct list { struct list *next; struct list *top; typedef struct list list;
查找文件:
find
find
能够迅速在指定范围内查找到文件。find命令的基本语法如下:find [OPTION] [path...] [expression]
linux-o5fc:~ # find /usr/ -name *.json -print /usr/share/doc/packages/perl-Params-Util/MYMETA.json /usr/share/plasma/layout-templates/org.opensuse.desktop.defaultPanel/metadata.json /usr/share/plasma/layout-templates/org.kde.plasma.desktop.appmenubar/metadata.json ...
find命令需要一个路径名作为查找范围,在这里是/usr/。find会深入到这个路径的每一个子目录中去寻找,因此如果指定“/”,那么就查找整个文件系统。-name 选项指定了文件名,在这里是所有以
.json
结尾的文件。-print 表示将结果输出到标准输出(在这里也就是屏幕)。注意find命令会打印出文件的绝对路径。find 命令还能够指定文件的类型。在Linux中,包括目录和设备都以文件的形式表现,可以使用-type
选项来定位特殊文件类型。
还可以通过指定时间来指导find命令查找文件。
-atime n
用来查找最后一次使用在n
天前的文件,-mtime n
则用来查找最后一次修改在n
天前的文件。但是在实际使用过程中,很少能准确确定n
的大小。在这种情况下,可以用+n
表示大于n
,用-n
表示小于n
。例如,/usr/bin/中查找最近 100 天内没有使用过的命令(也就是最后一次使用在 100 天或 100 天以前的命令)。$ find /usr/bin/ -type f -atime +100 -print
类似地,下面这个命令查找当前目录中,在最近一天内修改过的文件。
$ find . -type f -mtime -1 -print
更快速地定位文件:
locate
尽管 find 命令已经展现了其强大的搜索能力,但对于大批量的搜索而言,还是显得慢了一些,特别是当用户完全不记得自己的文件放在哪里的时候。这时,locate 命令会是一个不错的选择。如下:$ locate *.doc /fishbox/share/book/Linux从入门到精通.doc /fishbox/share/book/linux_mulu.doc /fishbox/share/book ...
这些搜索结果几乎是一瞬间就出现了。这不禁让人疑惑,locate 究竟是如何做到这一点的?事实上,locate 并没有进入子目录搜索,它有一点类似于Google的桌面搜索,通过检索文件名数据库来确定文件的位置。locate命令自动建立整个文件名数据库,不需要用户插手。如果希望立刻生成该数据库文件的最新版本,那么可以使用
updatedb
命令。运行这个命令需要有 root 权限,更新整个数据库大概耗时1分钟。在比较新的系统如CentOS7中默认并没有安装locate,可以通过
yum install mlocate
安装,OpenSUSE命令:zypper in mlocate
。第一次安装后需要先执行updatedb
生成数据库,然后就可以使用locate命令了。有时使用locate命令会找不到某个确实存在的文件,是因为数据库没有更新,locate每天自动更新一次数据库,有需要时可以手动执行updatedb
更新数据库应该就可以找到文件了。从终端运行程序
从终端运行程序只需要简单地键入程序名称即可。像 ls、find、locate 等这些所谓的 Linux 命令都只是一些程序而已。类似地,可以这样启动网页浏览器firefox
。$ firefox
按 Enter 键之后,当前终端会被挂起,直到 firefox 运行完毕(即单击关闭按钮)。如果希望在启动应用程序后继续在终端模拟器中工作,需要在命令后加上“&”,指导程序在后台运行。
linux-o5fc:~ # firefox & [1] 4728 linux-o5fc:~ #
此时,firefox 将运行在后台,终端继续等待接受用户输入。其中,4728表示这个程序的进程号。
查找特定程序:
whereis
whereis
命令主要用于查找程序文件,并提供这个文件的二进制可执行文件、源代码文件和使用手册页存放的位置。例如,查找find
命令:linux-o5fc:~ # whereis find find: /usr/bin/find /bin/find /usr/share/man/man1/find.1.gz /usr/share/man/man1p/find.1p.gz /usr/share/man/mann/find.n.gz /usr/share/info/find.info-1.gz /usr/share/info/find.info-2.gz /usr/share/info/find.info.gz
可以使用-b 选项让whereis命令只查找这个程序的二进制可执行文件。
linux-o5fc:~ # whereis -b find find: /usr/bin/find /bin/find
如果 whereis 无法找到文件,那么将返回一个空字符串。whereis 无法找到某个文件的可能原因是,这个文件没有存在于任何 whereis 命令搜索的子目录中。whereis 命令检索的子目录是固定编写在它的程序中的。这看起来多少有点像是个缺陷,但把搜索限制在固定的子目录如
/usr/bin
、/usr/sbin
和/usr/share/man
中可以显著加快文件查找的进度。用户及版本信息查看
在一台服务器上,同一时间往往会有很多人同时登录。who 命令可以查看当前系统中有哪些人登录,以及他们都工作在哪个控制台上。linux-o5fc:~ # who root pts/0 Dec 10 19:57 (:0)
有些时候,可能会忘记自己是以什么身份登录到系统,特别当需要以特定身份启动某个服务器程序时。这个时候,
whoami
这个命令会很有用。正如这个命令的名字那样,whoami
会回答“我是谁”这个问题。linux-o5fc:~ # whoami root
另一个常用的命令是 uname,用于显示当前系统的版本信息。带-a 选项的uname命令会给出当前操作系统的所有有用信息。
linux-o5fc:~ # uname -a Linux linux-o5fc 4.4.76-1-default #1 SMP Fri Jul 14 08:48:13 UTC 2017 (9a2885c) x86_64 x86_64 x86_64 GNU/Linux
在大部分时候,需要的只是其中的内核版本信息。此时可以使用
-r
选项。linux-o5fc:~ # uname -r 4.4.76-1-default
寻求帮助:
man
在 Linux 中获取帮助是一件非常容易的事情。Linux 为几乎每一个命令和系统调用编写了帮助手册。使用 man 命令可以方便地获取某个命令的帮助信息。$ man find
man命令在显示手册页时实际调用的是 less 程序。可以通过方向键或 J 键(表示向下)、K(表示向上)键上下翻动。空格键用于向下翻动一页。按下 Q 键则退出手册页面。
获取命令简介:
whatis
和apropos
man
手册中的长篇大论有时候显得太啰嗦了——很多情况下,人们只是想要知道一个命令大概可以做些什么。于是,whatis 满足了大家的好奇心。linux-o5fc:~ # whatis uname uname (1) - print system information uname (2) - get name and information about current kernel uname (1p) - return system name uname (3p) - get the name of the current system
whatis从某个程序的使用手册页中抽出一行简单的介绍性文字,帮助用户了解这个程序的大致用途。whatis的原理同locate命令基本一致。
与之相反的一个命令是
apropos
,这个命令可以通过使用手册中反查到某个命令。举例来说,如果用户想要搜索一个文件,而又想不起来应该使用哪个命令的时候,可以这样求助于apropos
。linux-o5fc:~ # apropos search apropos (1) - search the manual page names and descriptions ausearch (8) - a tool to query audit daemon logs ausearch-expression (5) - audit search expression format badblocks (8) - search a device for bad blocks bsearch (3) - binary search of a sorted array bsearch (3p) - binary search a sorted table bzegrep (1) - search possibly bzip2 compressed files for a regular expression bzfgrep (1) - search possibly bzip2 compressed files for a regular expression bzgrep (1) - search possibly bzip2 compressed files for a regular expression DBD::SQLite::Fulltext_search (3pm) - Using fulltext searches with DBD::SQLite find (1) - search for files in a directory hierarchy find (n) - search for classes and objects getgrnam (3p) - search group database for a name getpwnam (3p) - search user database for a name getpwuid (3p) - search user database for a user ID grep (1p) - search a file for a pattern hcreate (3p) - manage hash search table hsearch (3) - hash table management hsearch_r (3) - hash table management keyctl_reject (3) - Negatively instantiate a key specifying search error keyctl_search (3) - Search a keyring for a key ldapsearch (1) - LDAP search tool lfind (3) - linear search of an array lfind (3p) - find entry in a linear search table lkbib (1) - search bibliographic databases lookbib (1) - search bibliographic databases lsearch (3) - linear search of an array lsearch (3p) - linear search and update lsearch (n) - See if a list contains a particular element lzegrep (1) - search compressed files for a regular expression lzfgrep (1) - search compressed files for a regular expression lzgrep (1) - search compressed files for a regular expression manpath (1) - determine search path for manual pages match (1) - searches for patterns in files mgrep (1) - search mimencoded files for a regular expression oldfind (1) - search for files in a directory hierarchy res_nsearch (3) - resolver routines res_search (3) - resolver routines search.h (0p) - search tables strpbrk (3) - search a string for any of a set of bytes tdelete (3p) - manage a binary search tree tfind (3p) - search binary search tree tsearch (3) - manage a binary tree tsearch (3p) - search a binary search tree twalk (3p) - traverse a binary search tree wcschr (3) - search a wide character in a wide-character string wcscspn (3) - search a wide-character string for any of a set of wide characters wcspbrk (3) - search a wide-character string for any of a set of wide characters wcsrchr (3) - search a wide character in a wide-character string wmemchr (3) - search a wide character in a wide-character array xzegrep (1) - search compressed files for a regular expression xzfgrep (1) - search compressed files for a regular expression xzgrep (1) - search compressed files for a regular expression zgrep (1) - search possibly compressed files for a regular expression zipgrep (1) - search files in a ZIP archive for lines matching a pattern
可以看到,apropos 将命令简介(其实就是 whatis 的输出)中包含“search”的条目一并列出,用户总能够从中找到自己想要的。
总结:
Shell是一个用C语言编写的程序,它是用户使用Linux的桥梁。一直以来Shell以其稳定、高效和灵活成为系统管理员的首选。而命令行则是Linux的精髓。