对话 UNIX第 2 部分 做得多不如做得巧.docx
- 文档编号:23777033
- 上传时间:2023-05-20
- 格式:DOCX
- 页数:18
- 大小:25.46KB
对话 UNIX第 2 部分 做得多不如做得巧.docx
《对话 UNIX第 2 部分 做得多不如做得巧.docx》由会员分享,可在线阅读,更多相关《对话 UNIX第 2 部分 做得多不如做得巧.docx(18页珍藏版)》请在冰豆网上搜索。
对话UNIX第2部分做得多不如做得巧
Shell快捷方法可以减少键入等重复性劳动,从而节省精力和时间
了解如何利用UNIX®Shell提供的许多快捷方法。
通过一些练习,您将可以更灵活地、而不是更辛苦地进行工作。
每种技术性劳动都有其自身的秘密,这些小窍门、技巧和工具甚至可以处理最复杂的任务。
例如,我的邻居是一个熟练的木匠。
他仅凭眼睛就可以非常精确地测量和改变角度、无缝地进行斜接,并且他所完成的作品为他在当地报纸上赢得了赞誉。
但更神奇的是(至少对于我这样一个肯定会出错的外行来说),他可以相当轻松地完成工作。
他干这一行大约有20多年了,并且掌握了所有的快捷方法。
通过这些快捷方法,可以在这里节省一点点时间,在那里节省一点点劳动,然而对于像进行切割、锤钉子和组装框架这样的重复性任务,这样的节省最终加起来真的不少。
程序员、系统管理员和其他的UNIX®计算机专业人员都有他们自己专门的工具:
∙CPU
∙RAM
∙操作系统
∙应用程序
∙Shell
就像一个经验丰富的木匠,了解一些窍门并应用相应的工具可以节省大量的时间和精力。
第1期的对话UNIX 介绍了UNIX命令行的强大功能。
本文向您介绍一些有用的Shell快捷方法,它们有助于您更好地掌握Shell提示符。
让您的手指稍事休息,不要让它们过于疲劳
正如第1部分所介绍的,UNIX命令行的强大功能是无与伦比的。
只需按一些键并使用一些句法粘结剂,包括管道(|)、tee 和重定向,您就可以在Shell提示符中即兴组装自己的数据转换器。
例如,下面的命令将在您的home目录中查找所有包含单词 MonthlyReport 的文本文件:
$find/home/joe-typef-name'*.txt'-print|xargsgrep-l"MonthlyReport"
该命令将搜索整个home目录(find/home/joe)以查找所有的常规文件(-typef)中具有后缀 .txt 的文件,然后运行 grep 命令来搜索字符串 MonthlyReport。
如果找到匹配项,-l 选项将打印出相应的文件名。
因此,该命令的输出是匹配文件的列表。
尽管上面的命令很有用,但是要记住这个命令并重新输入,这样做很费劲,尤其是在您需要经常使用这个命令的情况下。
而且,当命令行作为使用电子邮件、文件、工具(如编辑器、编译器、监视器)和远程系统的主要接口时,您在命令行中所节省的时间和精力可以更好地用于手头上的其他任务。
毕竟,这些短的时间加起来真的不少。
为了处理这些重复性的任务,UNIXShell提供了各种有用的快捷方法,具体包括:
∙符号
∙通配符
∙命令历史
∙环境变量
∙别名
∙启动文件
例如,您可以使用符号 ~(波浪符号)引用您的home目录。
您还可以使用 $HOME 环境变量引用您的home目录,如清单1 所示。
清单1.UNIXShell中的快捷方法
$whoami
strike
$echo~
/Users/strike
$echo$HOME
/Users/strike
$!
!
echo$HOME
/Users/strike
最后一个命令 !
!
(两个感叹号),可能看起来有些奇怪,但它是一种命令历史符号,可以一字不差地重复前面的命令。
(许多Shell还允许您使用向上箭头键或按Control+P来浏览以前的命令列表。
)
让我们更仔细地研究Shell中的各种快捷方法。
本文主要介绍ZShell(zsh,请参见参考资料部分),它通常安装在/bin/zsh目录中。
(如果您的系统中没有ZShell,可以请求系统管理员安装它。
)ZShell具有一些特别的特性,另外,这里所介绍的示例适用于所有主流的UNIXShell。
回页首
Shell符号
针对许多频繁使用的命令行参数,Shell提供了相应的符号 或记号作为简写。
您只需输入这些符号来代替相应的参数。
如上所述,~ 表示您的home目录。
与之类似的简写形式 ~username 表示username的home目录。
例如,~joe 表示joe的home目录,所以,要将文件从joe的doc目录复制到您的info目录,您可以输入下面的命令:
$cp~joe/doc/report.txt~/info
假设joe的home目录位于/guests,而您的home目录为/staff/bobr,~joe 将由 /guests/joe 替换,而 ~ 则变成 /staff/bobr,最后产生命令 cp/guests/joe/doc/report.txt/staff/bobr/info。
(请参见侧栏“检验您的工作”以了解如何预览命令行。
)
检验您的工作
如果您想要查看命令行符号扩展后的结果,可以使用echo 命令:
$ echo~joe/doc/report.txt~/info/guests/joe/doc/report.txt/staff/bobr/info$ echo$SHELL /bin/zsh$ ls architecture.txtServices.pdfservices.txtSchema.pdf$ echo*.txt architecture.txtservices.txt
echo 命令将完整地表达您在命令行中输入的内容。
然而,因为Shell会在调用任何程序之前,对(大多数)命令行参数进行扩展,所以该命令将打印出所有替换的结果。
(Shell环境变量 $SHELL 包含当前正在运行的Shell的名称。
)
另一个有用的符号是 ..(两个点号),这是当前目录的父目录的简写。
使用 .. 和 .(当前工作目录的简写符号),您可以引用文件系统中相对于当前工作目录的文件和目录。
例如,如果您的当前工作目录为~/jane/projects/lambda,那么简写 ../.. 表示向上两级目录的目录,即~/jane。
要表示包含~/jane的目录,您可以使用 ../../../(“向上三级目录”)或路径 ~jane/../。
后面的这个路径表示从~jane开始,然后转到上一级目录。
要将文件复制到您的当前目录,不需要指定目标目录,可以直接使用.(“点”)来表示:
$cp-pr/path/to/lots/of/stuff.
前面的命令将/path/to/lots/of/stuff目录递归地复制到您的当前目录,并保持其原始的时间和日期戳。
引用 .. 和 . 的路径名称为相对路径名。
以/(正斜杠)或~(波浪符号)开头的路径名称为绝对路径名,因为您是从文件系统的顶端、或从一个目录层次结构的顶端开始来引用相应的文件。
回页首
通配符和模式
使用符号,可以节省输入的时间,并且可以快速和精确地引用特定的目录。
通配符 是另一种简写形式,用来引用目录中的内容。
例如,假设您的某个目录中包含了100个文件。
有些是以 .c 为后缀的C源代码文件,其他一些是以 .o 为后缀的目标文件,还有一些是文本文件(.txt)、脚本(.sh)和可执行文件(具有执行权限的文件)。
要仅列出其中的 C 文件,只需输入:
$ls*.c
通配符 *(通常称为 star 而不是 asterisk)表示匹配任何字符序列。
.c 文件扩展名是一种文本模式,它仅匹配点号加小写字母 c 的情况。
所以,*.c 表示任何字符序列加上点号和小写字母c。
在给定了 *.c 之后,Shell将查看当前目录(除非您提供一个起始绝对或相对路径名),找出所有匹配这个模式的文件名,将 *.c 扩展为文件名列表,然后将这个列表作为参数传递给 ls 命令。
清单2 基于 wget 的源代码文件演示了 *.c 的使用,wget 是一种命令行的下载实用工具。
ZShell通配符匹配操作符
ZShell具有一些独特的和不可多得的通配符匹配操作符。
下面是其中一些典型的操作符。
**/ 通配符匹配操作符展开为所有的下级目录,包括当前工作目录。
可以将 **/ 看作内置的 find 命令。
再次使用 wget 源代码,您可以使用下面的命令查找所有的Makefile:
$ echo**/Makefile Makefiledoc/Makefilepo/Makefilesrc/Makefileutil/Makefilewindows/Makefile
如果您不打算包含当前工作目录,那么只需输入*/**/,如下面的示例所示:
$ echo*/**/Makefile doc/Makefilepo/Makefilesrc/Makefileutil/Makefilewindows/Makefile
另一种有用的ZShell通配符匹配操作符可以匹配文件类型。
提供与前面相同的模式,但需要追加(.)、(/)、(*) 或 (@),以便分别匹配常规文件、目录、可执行文件和符号链接:
$ls-d-F*(/) ChangeLog-branches/doc/po/src/util/windows/
ZShell还为 (/) 表达式提供了一种快捷方法。
只需在模式的末尾添加一个正斜杠,就可以将输出结果限定为目录:
$ ls-d*/ ChangeLog-branches/doc/po/src/util/windows/
清单2.使用通配符在目录中查找C源代码文件
$ls*.c
alloca.c
ansi2knr.c
cmpt.c
connect.c
convert.c
...
将通配符展开为匹配文件名列表的过程称为通配符匹配(globbing),并且UNIXShell具有各种各样的通配符匹配操作符(所谓的 glob),以便帮助您描述所要查找的内容:
∙通配符匹配操作符 *(星号)匹配任何字符或字符序列,包括空序列。
∙通配符匹配操作符 ?
(问号)匹配任何单个的字符。
∙通配符匹配操作符 [](方括号)匹配任何括起来的字符。
在方括号中,通过使用 -(连字符),比如 [a-z] 或者所有的小写字母,您可以引用某个范围的字符。
(ZShell具有许多独特的通配符匹配操作符。
有关 ZShell通配符匹配操作符的更多信息,请参见侧栏。
)
您还可以根据需要重复使用通配符匹配操作符。
清单3 提供了一些其他示例。
在清单3 中,命令1显示了该目录中所有的条目,包括长列表中那些以.(点)开头的条目。
(-a 选项显示了所谓的点文件;-1 选项表示在一列中列出所有的内容;而 -F 选项分别使用/(正斜杠)和*(星号)突出表示目录和可执行文件。
)
命令2查找名称以点号开头的条目(即.*)。
第3个命令仅查找那些单字母后缀的项目。
第4个命令仅查找那些4个字母后跟点号和单个字符的项目。
最后,命令5查找这样的项目:
以小写字母 a、b 或 c 开头,后面至少跟一个字母,然后可以是任何内容,接着是点号和任何后缀。
正如所看到的,您可以根据实际情况重复使用这些通配符匹配操作符。
清单3.通配符示例
1$ls-1-a-F
./libs
ChangeLog
ChangeLog-branches/
Makefile
Makefile.in
alloca.c
ansi2knr.c
cmpt.c
cmpt.o
config.h
config.h.in
connect.c
connect.h
connect.o
convert.c
convert.h
convert.o
...
wget*
2$ls-a-F.*
./lib
3$ls-1*.?
alloca.c
ansi2knr.c
cmpt.c
cmpt.o
config.h
connect.c
connect.h
connect.o
convert.c
convert.h
convert.o
...
4$ls-1?
?
?
?
.?
cmpt.c
cmpt.o
5$ls[a-c]?
*.*
alloca.c
ansi2knr.c
cmpt.c
cmpt.o
config.h
config.h.in
connect.c
connect.h
connect.o
convert.c
convert.h
convert.o
cookies.c
cookies.h
cookies.o
那么,ls*.z 将会产生什么样的结果呢(假设不存在这样的文件)?
它将产生一条有用的错误消息:
$ls*.z
zsh:
nomatchesfound:
*.z
回页首
关于(命令)历史
到目前为止,您已经了解了如何指定路径和选择相应的文件。
您可以在命令行中描述需要完成的任务。
然而,即使所有的命令行都很短并且很简单,但您仍然有可能对反反复复地输入这些相同的内容而感到厌烦。
尤其是,您可能厌倦了输入冗长的、复杂的命令行,其中可能包含大量的选项、或者参数的顺序有严格的要求。
幸运的是,大多数Shell都维护了以前命令的历史。
要再次运行一个命令,只需从这个历史列表中找到相应的条目,然后再次运行它。
与Shell中其他的部分一样,通过快捷方法可以快速和轻松地进行引用。
要在ZShell中启用命令历史,可以输入:
$HISTSIZE=500
$SAVEHIST=500
这里的命令指定了Shell和持久化历史文件应该保留最后的500条命令。
(在缺省情况下,ZShell仅保存最后的30条命令。
)有关如何捕获和保存命令历史的信息,请查看您的Shell文档。
在Shell中进行了一段时间的工作之后,您只需输入 history 就可以查看命令历史:
$history
...
781/bin/ls-d*/
782/bin/ls-F*(/)
783/bin/ls-d-F*(/)
784/bin/ls-d-F*/
785/bin/ls-d*/
您所运行的每个命令都会分配到一个顺序的数值标识符。
您可以使用这个标识符,如 782,来引用完整的命令和命令中的某些部分。
要再次运行一个命令,可以输入 !
(感叹号)加上命令对应的数值:
$!
785
ChangeLog-branches/doc/po/src/util/windows/
如果您希望从一个历史命令中获得特定的参数,可以使用!
(感叹号)来引用这个命令,并提供 :
N,其中 0 表示命令名,1 表示第1个参数,依此类推。
例如,要提取历史日志中命令782的第二个参数,可以输入清单4 中所示的代码。
清单4.提取命令782的第二个参数
$echo!
782:
2
echo*(/)
ChangeLog-branchesdocposrcutilwindows
$lsAUTHORSCOPYINGINSTALLMACHINES
AUTHORSCOPYINGINSTALLMACHINES
$echo!
!
:
3
echoINSTALL
$history-2
788lsAUTHORSCOPYINGINSTALLMACHINES
789echoINSTALL
$echo!
788^
echoAUTHORS
AUTHORS
$echo!
788$
echoMACHINES
MACHINES
命令 history-2 打印出前两个命令。
作为快捷方法,您可以使用 ^(脱字符号)引用命令的第一个参数(而不是命令名本身),并且您可以使用 $(美元符号)引用历史命令的最后一个参数。
您还可以使用范围符号来引用某个范围的参数,如清单5 所示。
清单5.范围符号
$echoAUTHORSCOPYINGINSTALLMACHINES
AUTHORSCOPYINGINSTALLMACHINES
$echo!
!
:
1-2
echoAUTHORSCOPYING
AUTHORSCOPYING
还有其他的更直接的方法可以用来再次调用历史命令。
其中一种方法是搜索历史命令:
$lsI*
$lsM*
$echo!
?
M
lsINSTALL
结构 !
?
M 寻找最近的包含大写字母 M 的历史命令行。
回页首
环境变量
流畅地表达命令行 任务,这是一种基本的UNIX技能。
但是与UNIX进行对话不仅仅只是使用Shell提示符,您还必须与各种各样的UNIX实用工具进行通信。
在UNIX中,环境变量保存了Shell中的相关设置,并允许您将首选项传播到从命令行启动的所有实用工具中。
有些环境变量称为 Shell变量,Shell仅使用这些变量控制其自身的行为。
例如,只有ZShell使用 $HISTSIZE 和 $SAVEHIST 管理命令历史,如上所述。
可以将Shell变量看作相应的设置。
需要对其他的环境变量进行导出、或使得它们全局可用,并将它们复制到从命令行中启动的每个命令的进程空间(即环境)。
例如,$HOME 是一个特殊的环境变量,它保存了您的home目录的位置。
UNIX登录序列将设置 $HOME(以及其他的环境变量),然后启动Shell,而Shell反过来使用 $HOME 查找所有的Shell启动文件。
您所启动的其他应用程序,如SSH和FTP,引用 $HOME 查找.netrc文件(用于存储机密的、远程访问的密码)。
有些环境变量,如 $HOME、$PATH 和 $SHELL,会被所有应用程序使用。
其他的环境变量可能专门针对某个应用程序。
要查看当前所有的环境变量,可以输入 printenv,如清单6 所示。
(根据系统管理员对系统所进行的配置,您系统中的环境变量可能会比本文中所介绍的更多或更少。
)
清单6.查看环境变量
$printenv
PATH=/Users/strike/bin:
/Applications/xampp/xamppfiles/bin:
/Users/strike/bin:
/usr/bin:
/
bin:
/usr/sbin:
/sbin
HOME=/Users/strike
SHELL=/bin/zsh
USER=strike
TERM=xterm-color
LOGNAME=strike
SHLVL=1
PWD=/Local/src/versions/wget/wget-1.9
OLDPWD=/Local/src/versions/wget/wget-1.9/src
PERL5LIB=/Applications/xampp/xamppfiles/lib/perl5/site_perl/5.8.7:
/Projects/IGSP/src
CLICOLOR=true
MANPATH=/Local/root/share/man:
/usr/share/man:
/opt/local/share/man
INFOPATH=/opt/local/share/info
LESS=-n
您可能认识其中大多数的变量,而其他一些可能是新出现的。
Shell级别($SHLVL)显示您所处的Shell的深度。
1 表示登录Shell,2 表示您从登录Shell中启动了另一个Shell,依此类推。
您可以使用 $SHLVL 的值来更改后续Shell(嵌套Shell)的提示符。
$TERM 反映了您的终端(可能是终端模拟程序)设置,对于确保正确地呈现文本、颜色以及对按键进行正确的解释,这是非常重要的信息。
$PWD 是您的当前工作目录,而$OLDPWD 是上一次的工作目录。
您可以使用这两个变量实现在两个目录之间的快速切换,如清单7 所示。
清单7.在目录之间进行切换
$echo$PWD
/Users/strike
$echo$OLDPWD
/Local/src/versions/wget/wget-1.9
$cd$OLDPWD
$echo$PWD
/Local/src/versions/wget/wget-1.9
$echo$OLDPWD
/Users/strike
上面列表中剩下的环境变量都是应用程序特定的。
每个环境变量保存了相应的首选项设置,当您启动了与之关联的应用程序后,它可以用于控制该应用程序的工作方式。
$PERL5LIB 是Perl查找自定义库的搜索路径。
ls 命令使用 $CLICOLOR 通过不同的颜色呈现不同类型的文件(目录为蓝色、可执行文件为绿色,等等)。
程序的man页面中通常包含对自定义应用程序环境变量的说明。
设置环境变量与设置Shell变量的方法相同。
然而,您必须导出该变量,以使得它全局可用:
$MYVARIABLE=$HOME/projectX
$exportTMPDIR=/tmp/projectX
前一个命令设置了名为 $MYVARIABLE 的Shell变量。
(开头的美元符号是Shell提示符。
您在设置变量时,不用提供这个$符号。
然而,当您使用这个变量时,必须使用美元符号,比如 $MYVARIABLE。
)$MYVARIABLE 仅对Shell是可见的,因为没有将其导出。
要查看所有Shell变量的列表,可以输入 set。
set 的输出包括环境变量,因为它们对Shell来说也是可用的。
在后面的一个命令中,设置并导出了 $TMPDIR,因此它对于从Shell中启动的所有应用程序都是可用的。
GNUCompilerCollection(GCC)编译器是一个使用 $TMPDIR 的应用程序。
$TMPDIR 中所存储的值表示GCC用来存放生成的临时文件的位置。
如果您要删除一个环境变量,只需输入 unset 加上变量名即可,如清单8 所示。
清单8.删除环境变量
$set
HOME=/Users/strike
MYVARIABLE=/Users/strike/projectX
TMPDIR=/tmp/projectX
...
$unsetMYVARIABLETMPDIR
$set
HOME=/Users/strike
....
回页首
别名和启动文件
前面的部分主要关注的是如何减少在命令行中的输入。
当然,还有许多内容需要学习,因为Shell环境非常丰富。
然而请记住,功能越强大,生产能力就越大(要对蜘蛛侠说声抱歉,因为修改了原话)。
为了保留以前输入的内容和保存以前的所有设置,UNIXShell分别提供了别名和启动文件。
别名 是您所创建的快捷方法。
每次Shell启动时都会读取启动文件,这是保存(和共享)所有Shell设置的理想的地方,如Shell变量(选项)、环境变量和别名。
别名是一个简短的序列,您可以使用它来代替一个较长的命令。
您可以把别名看作是一个命令行的缩写。
无需输入:
$find/home/joe-typef-name'*.txt'-print|xargsgrep-l"MonthlyReport"
在命令提示符处,您可以输入已经创建的别名:
$findreports
Shell减少了工作的复杂程度,它会将 findreports 替换成
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 对话 UNIX第 部分 做得多不如做得巧 UNIX 得多 不如