linux混合命令_十多个命令行混合

这是“口语UNIX”系列的第十三期:我想这是一个不祥的数字,直到我在Internet上扫描了该数字的危害性来源。 事实证明,十三个方面的“好”和“坏”比例大致相等(请参阅参考资料 )。

优点:十三是铝的原子序数,是无数解放的首选容器; 篮球职业选手威尔特·张伯伦(Wilt Chamberlain)穿了13号(你们都知道威尔特有多“幸运”); 在一种禁忌变换中,十三是第七质数,而七是非常幸运的。

坏处:绞刑架(显然)有十三步; 派对撞车者Loki和Judas第十三到达。 不管您如何将它切成两,三,四或六,一张十三张桌子都很难在餐厅坐下,这也许可以解释为什么Loki和Judas被认为是局外人。

陪审团充其量只有十三岁。 因此,除非您在13日(星期五)在位于模仿鸟巷1313号(拥有自己历史的土地)上建的办公大楼的13层阅读,否则是时候庆祝了。 现在,“说UNIX”是个满脸表情的少年。 这里有十种命令行混合和外壳斯诺克游戏,以庆祝它进入青春期。 梅泽尔电视!

临时设置环境变量

环境变量(例如EDITOR和TZ)会影响命令的结果。 (前者选择要启动的程序来编辑文本;后者指定您的时区。)通常,您在外壳启动文件中设置环境变量以影响整个外壳会话,并且可以在以下位置更改外壳会话的值:任何时候都可以使用export TZ=GMT类的命令。

此外,您可以临时更改单个命令的环境变量的值。 只需在命令行和要运行的命令的开头设置环境变量。 例如,要更改单个命令的首选编辑器,请使用EDITOR= editor ,如下所示:

$ printenv
...
EDITOR=vi
...
$ EDITOR="pico" less bigfile

此组合在较少的情况下分页bigfile 。 如果您在less中键入v以编辑文件,则会启动pico而不是vi 。 这是另一种实际用途:

$ date
Sun Aug  5 16:14:17 EDT 2007
$ TZ="Japan" date
Mon Aug  6 05:14:06 JST 2007

对TZ的临时更改会影响date的即时实例如何解释系统的当前日期和时间。

发现您真正在运行什么

大量的Shell功能会影响您键入的命令名称的解释方式。 每个外壳都有各种内置命令。 PATH环境变量指定要搜索的目录的列表和顺序; 并且每个别名都充当速记。 有这么多种方式运行程序,您如何知道实际执行的是什么? 使用外壳程序的内置type命令来揭示真相。

假设您具有以下外壳程序设置:

PATH=/bin:/usr/bin:/usr/local/bin
alias vi=pico

您可以在/ usr / bin和/ usr / local / bin中找到Perl的副本。 要查找您正在使用的Perl,请type perl

$ perl -v 
This is perl, v5.8.7 built for darwin-2level
$ type perl
perl is /use/local/bin/perl
$ type -a perl
perl is /usr/local/bin/perl
perl is /usr/bin/perl
$ type -a -w perl
perl: command
perl: command

type perl命令显示了如何在命令行上解释perl命令。 在这里,/ usr / local / bin / perl是扩展名。 type -a命令显示外壳程序知道的Perl的所有实例,这在很大程度上取决于PATH变量。

尝试type与您通常使用一些其他的命令:

$ type -a vi
vi is an alias for pico
vi is /usr/bin/vi
$ type -a cd
cd is a shell builtin
cd is /usr/bin/cd

type命令显示vi实际上是pico的别名。 type命令还显示cd是内置命令,在外部被复制为/ usr / bin / cd。

使查找更加便携

在过去的一年中,您已经findfind许多用途,但是我省略了一个使find命令行可移植到其他操作系统的选项。

按照惯例,在UNIX®系统上查找带有空格的文件名是不寻常的。 但是,更长的,更具描述性的文件名在Mac OS X和Microsoft®Windows®中很常见,随着操作系统积累了更多的桌面功能,它们在UNIX上也变得越来越普遍。 毕竟,将报表另存为2007 Business Plan比bizplan07.ooo更为明显。

find命令枚举带有嵌入式特殊字符的长文件名,但是,如果要将find与另一个命令结合使用,最安全的方法是使用NUL字符而不是空格来分隔列表中的各个文件名。 让我们来看看区别。

假设您有三个文件夹,每个文件夹的名称中都包含一个或多个空格:

$ ls -1
Business Plan 2007
Expense Report
Pictures from Spain

如果对这样的一批文件运行find并将结果列表传递给xargs ,则文件名中的空格会导致错误:

$ find . -type f -print | xargs ls -1
ls: ./Business: No such file or directory
ls: ./Expense: No such file or directory
ls: ./Pictures: No such file or directory
ls: 2007: No such file or directory
ls: Plan: No such file or directory
ls: Report: No such file or directory
ls: Spain: No such file or directory
ls: from: No such file or directory

传递给xargs的结果是单个字符串. ./Business Plan 2007 ./Expense Report ./Pictures from Spain . ./Business Plan 2007 ./Expense Report ./Pictures from Spain 。 默认情况下, xargs用空格(或换行符)分隔输入以生成要操作的文件列表。 在这里,由于文件名包含空格,因此该规则将生成错误的列表,如上所示。

适当的可移植技术是将find -print0xargs -0结合使用,以NUL字符分隔文件名。 这是最受欢迎的方法:

$ find . -type f -print0 | xargs -0 ls -1
./Business Plan 2007
./Expense Report
./Pictures from Spain

顺便说一句,如果要预览xargs生成的命令,请添加选项-p-t-p选项显示每个伪造的命令并提示您进行授权。 键入大写或小写的y来运行该命令,并键入其他任何内容来拒绝它。 -t选项在执行每个命令之前将每个命令回显到stderr

找到更多乐趣

尽管find无限有用,但它具有两个隐式设置,这些设置会限制其结果(并可能使您-name ):-名称匹配区分大小写,并且文件系统遍历不遵循符号链接。

因此,开始find -name '*plan*'的命令会忽略名称中任意位置带有字符串Plan的文件,并且当您的主目录中有一个指向音乐的符号链接指向TB级媒体时,该命令无法对音乐进行分类存储在/ media / music上。

您可以使用-iname覆盖区分大小写的匹配项,并且可以使用-follow遍历符号链接。 这是同时应用这两个选项的示例:

$ alias ls='ls -aF'
$ ls -1 
bin/
lib/
src/
tomb/
tunes@
$ find . -name '*music*' -type f -print 
$ find . -iname '*music*' -type f -print 
$ find . -name '*music*' -type f -follow -print 
$ find . -iname '*music*' -type f -follow -print 
./tunes/Muse/Origin Of Symmetry/04 Hyper Music.m4a
./tunes/Radiohead/OK Computer/04 Exit Music (For A Film).mp3

-F选项产生的@符号注释所示, tunes是符号链接。 要查找所有带有字符串“ music”的任何变体的歌曲,必须使用-iname *music* 。 要遍历调整点的层次结构,必须使用-follow

例如,要使find更具可移植性并且类似于Spotlight的搜索功能,请使用-print0 -follow -iname pattern

轻松收集许多命令的输出

您可以使用> output>> output修饰符轻松捕获命令行的>> output ,其中前者创建或覆盖文件output ,后者附加到output 。 您可以组合使用两个修饰符来生成一系列命令的笔录,这在尝试快照系统状态时非常有用,例如:

$ ps > state.`date '+%F'`
$ w >> state.`date '+%F'`

后面打勾或反引号操作符( ``代替扩展命令。 在shell解释命令行时,将在反刻度之间运行命令,并且命令的输出将在最终扩展中使用。 这里,参数周围的单引号使它保持完整,从而防止外壳程序解释+%

在这两个命令之后,将创建文件state.YYYY-MM-DD,例如state.2007-08-05 ,其内容类似于以下内容:

PID TTY          TIME CMD
 9997 pts/1    00:00:00 zsh
10351 pts/1    00:00:00 ps

 17:56:04 up 21 days,  2:53,  2 users,  load average: 0.89, 0.94, 0.91
USER     TTY      FROM              LOGIN@   IDLE   JCPU   PCPU WHAT
adamgood pts/0    c-67-169-182-255 Sat17    0.00s  0.37s  0.36s pine
mstreich pts/1    cpe-071-065-224- 17:17    0.00s  0.01s  0.00s w

但是,每次键入后退标记操作都很麻烦。 您可以将序列替换为:

$ file=state.`date '+%F'`
$ ps > $file
$ w >> $file

但这只是效率更高,而且仍然容易出错,因为在第二个或后续命令中使用>而不是>>相当容易。 捕获一系列命令输出的最简单方法是将它们组合在大括号({})中。

$ { ps; w } > state.`date '+%F'`

运行ps命令(列出用户当前的进程),然后运行w (显示谁在使用计算机),然后将收集的输出捕获到文件中。

注意:您也可以在括号中嵌入命令序列以达到相同的结果。 但是,有一个重要的区别。 括号中收集的一系列命令在子shell中运行,并且不会影响当前shell的状态。

例如,您可能期望以下顺序:

$ { cd $HOME; ls
      -1}; pwd

产生与以下相同的输出:

$ (cd $HOME; ls); pwd

花括号中的命令更改当前外壳程序的工作目录。 后一种技术是惰性的。 使用组合还是子Shell取决于您的意图-尽管子Shell的功能要强大得多,如下所述。

抢救子弹!

虽然通常运行一个子shell来将汇总输出通过管道传递给单个命令,但是您也可以使用子shell来在适当位置扩展命令,就像反勾号一样。 更好的是,一个子shell可以包含另一个子shell,因此扩展也可以嵌套。

让我们开始吧。

$ {ps; w} > state.$(date '+%F')

此命令与{ ps; w } > state.`date '+%F'` { ps; w } > state.`date '+%F'`$( )表示法在括号内运行命令,然后将其自身替换为输出。 换句话说, $()会在适当的位置扩展,就像后退标记一样。 但是,与反向滴答不同, $( )可能非常复杂,甚至可以包括其他$( )扩展。 这里有些例子:

$ (cd $(grep strike /etc/passwd | cut -f6 -d':'); ls)

此命令在密码文件中搜索用户删除的条目,剪切主目录(密码文件中的字段六,如果从零开始计数的话)字段,切换到该目录并列出其内容。 grep /etc/passwd strike | cut -f6 -d':'的输出 grep /etc/passwd strike | cut -f6 -d':'在进行任何其他操作之前已展开到位。

这是另一个示例,这次用户名使用whoami从环境中获取:

(cd $(grep $(whoami) /etc/passwd | cut -f6 -d':'); ls)

由于子外壳有很多用途,因此您可能更喜欢始终使用它,而不是组合使用或使用反滴答运算符。

停止输入长路径名

诸如PATH和MANPATH环境变量之类的功能可节省键入。 这两个变量都定义了一系列目录,分别用于搜索可执行文件和手册页。

该外壳程序支持另一个搜索路径:CDPATH。 顾名思义,CDPATH枚举目录列表以搜索命名目录。 让我们看看它是如何工作的。

假设您的主目录中有三个目录,分别是“墓”,“当前”和“个人”。 该墓目录包含旧的工作项目; 当前包含您积极从事的工作; 和个人包含符合您兴趣的文件等。 表演ls -R tomb current personal发现像这样的东西:

$ ls -R tomb current personal
current:
./        ../       einstein/ herbie/

personal:
./       ../      fishing/ novel/

tomb:
./       ../      mariner/ marvin/  voyager/

在没有CDPATH的情况下,采用这种结构,更改到任何目录都要求您记住文件夹的位置,并键入其完全限定(或相对)的路径名:

$ cd ~/tomb/mariner
$ cd ~/personal/novel
$ cd ~/current/einstein

为了简化这项工作,请将CDPATH设置为您要搜索命名目录的目录列表:

$ export CDPATH=.:~/:..:../..:

这是CDPATH的最小设置。 它按顺序搜索当前目录( .或“点”),主目录(〜/),父目录( ..或“点点”)和祖父母目录( ../.. )。 最低设置倾向于使用本地目录和相对靠近的目录。

设置了此CDPATH后,您可以快速切换到任何顶级目录:

$ pwd
/tmp
$ cd current
/home/strike/current
$ cd personal/fishing
/home/strike/personal/fishing
$ cd novel
/home/strike/personal/novel
$ cd /tmp
$ cd personal/novel
/home/strike/personal/novel
$ cd /tmp
$ cd novel
cd: no such file or directory: novel

在除最后一个cd命令之外的每个命令中,该参数都与CDPATH中的目录匹配。 但是,由于个人目录尚未位于CDPATH中,因此无法找到它(如果您位于相对路径之外)。

如果要搜索个人目录和其他两个目录,请在最后一个冒号之后或以您希望搜索的任何顺序将它们添加。 假设前面的export命令在您的shell启动文件中,请添加三个目录:

$ export CDPATH=$CDPATH:~/current:~/tomb:~/personal

现在,您只需键入要切换到的目录的名称:

$ cd current
/home/strike/current
$ cd /tmp
$ cd einstein
/home/strike/current/einstein
$ cd fishing
/home/strike/personal/fishing
$ cd personal/novel
/home/strike/personal/novel

与PATH和MANPATH一样,如果CDPATH中有多个条目包含匹配项,则搜索从第一个匹配项结束。 例如,如果您将一个名为Novel的目录添加到tomb,则cd novel命令将产生〜/ tomb / novel。

$ mkdir ~/tomb/novel
$ cd /tmp
$ cd novel
/home/strike/tomb/novel
$ cd personal/novel
/home/strike/personal/novel

当CDPATH的条目包含唯一的目录名称时,其效果最佳。 否则,请像个人/小说一样键入足够的区分路径。

减少工作量

您已经看到了许多关于在UNIX系统中广泛使用文本文件的示例。 大多数系统启动文件都是文本文件,外壳脚本,配置文件当然还有数据文件都是文本文件。 除文本编辑器外,下一个最有用的实用程序是寻呼机,或使您可以逐页浏览文本文件的应用程序。

该应用程序较少,是最受欢迎的寻呼机之一,并且它提供了大量的选项来调整其行为。 实际上,您可以将LESS环境变量设置为选项列表,以控制less的默认工作方式。 这是一组有用的选项:

export LESS="-Nmsx4"
  • -N显示行号。
  • -m以百分比显示文件中的当前位置。
  • -s将多个空白行“压缩”或减少为单个空白行。
  • x4每四个空格设置一个制表位。

花一些时间在较少的手册页上,以找到对您最有用的选项。

从下至上读取文件

UNIX系统上的许多文件会不断增长,直到被截断或存档为止。 例如,最重要的系统过程(例如电子邮件传输和远程访问)会连续记录活动,并将每个新条目附加到文件末尾。 最有趣的是日志文件的结尾。 如果服务崩溃,那么最后发生的事件将提供最多的线索。

有两种方法可以以相反的顺序显示文件中的行: taccat的反面)和命令tail -r

$ cat smallfile
a
b
c
$ tac smallfile
c
b
a
$ tail -r smallfile
c
b
a

您可能会发现tac更实用,因为它发出整个文件,而不是tail ,而不是tail ,该文件将输出截断为若干行。 例如,您可以结合使用tacless来创建一个别名,以反向方式分页文件:

$ alias rless="LESSOPEN='|tac %s' less"
$ rless smallfile
c
b
a

rless别名临时将LESSOPEN(一个专门针对less的环境变量)设置为|tac %s 。 这将强制每个文件( %s是文件名的占位符)由tac进行预处理(因此,管道| )。

这是相同技巧的另一种变体,但是它利用了perl而不是tac ,这可能在您的系统上不可用:

LESSOPEN="|perl -e 'print reverse (<>)' %s" less small

perl行说:“将所有输入行读入一个匿名数组( (<>) ,反转元素的顺序,然后打印新数组。”

做新数学

如果您需要计算结果,则无需跳转到新的应用程序。 您可以在命令行中舒适地呆着。 您可以使用dc (反抛光符号计算器)或bc (用于数学的整个脚本语言)。 或者,如果您只是需要快速回答,请使用命令行和$(( ))运算符。

$ echo $(( 100 / 10 ))
10
$ echo $(( 10 ** 2 ))
100

Shell并没有大量算术运算符,但是对于大多数编程任务(包括按位移位,余数和比较)而言,它就足够了。

有足够的成长空间

“说UNIX”可能是13点,但仍有很多经验。 有更多的命令和窍门可供学习,有许多概念需要探索,更不用说有大量开放源代码软件可以提高您的生产力。

哦,以免我忘了,牙套必须脱落。 高年级学生有一种仪式上的困扰,一些真正令人尴尬的时刻,并保持稳定。 或者,也许我正在显示自己的年龄。 。 。 孩子们还是会稳定下来,对吗?

谢谢阅读。 希望您到目前为止喜欢本专栏。


翻译自: https://www.ibm.com/developerworks/aix/library/au-speakingunix13/index.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值