UNIX 生产力技巧

提高办公工作效率的有价值的命令行秘诀

在日常的办公环境中使用 UNIX® 并不一定是非常笨拙的。使用 UNIX Shell 的强大功能和可用的系统工具可以极大地提高您在办公中的工作效率。

Michael Stutz (stutz@dsl.org), 作家, 顾问

Michael Stutz 是 The Linux Cookbook 一书的作者,他仅使用开放源码软件对该书进行了设计和排版。他的研究兴趣包括数字出版和图书的发展未来。他使用各种 UNIX 操作系统已有 20 多年。您可以通过 stutz@dsl.org 与他联系。



2007 年 6 月 25 日 (最初于 2006 年 9 月 19 日)

引言

UNIX® 命令行的语言以功能全面而著称,通过使用各种小型工具、实用程序,并在 Shell 中将它们组合在一起执行,您可以指定许多精确的和复杂的任务。

但是,当在办公环境中使用它们时,同样的这些工具可能成为提高您工作效率的功能强大的助手。许多 UNIX 独特的技巧可以用于提高工作效率。

对于使用命令行来改善办公工作效率,本文给出了一些建议和技巧,包括如何查看当前系统习惯、如何计算工作花费的时间、操作日期的秘诀、使用快速而简单的方法对自己发送提醒、对重复性交互任务实现自动化的方法。

查看日常的习惯

使用 UNIX 命令行提高办公工作效率的第一步是,仔细地研究您当前的日常习惯。通过通常所使用的工具和应用程序以及访问和修改的文件,可以告诉您究竟是什么样日常工作占用了大量的时间,以及应该避免哪些操作。

查看所使用的工具

您需要查看经常使用哪些工具和应用程序。可以轻松地在 Shell 的内置 history 中查明您的日常工作习惯,它将输出在当前的和过去的会话中发送给 Shell 的输入行内容的枚举清单。有关典型的示例,请参见清单 1

清单 1. Shell 的内置 history 的示例输出
$ history
1 who
2 ls
3 cd /usr/local/proj
4 ls
5 cd websphere
6 ls
7 ls -l
$

真实的历史记录通常保存在一个文件中,以便能够提供给将来的会话,例如,Korn Shell 将其命令历史记录保存在用户 home 目录的隐藏文件 .sh_history 中,而 Bash Shell 则使用 .bash_history。通常在达到一定的长度后,会对这些文件进行覆盖,但是许多 Shell 具有设置最大历史记录长度的变量,Korn 和 Bash Shell 具有 HISTSIZEHISTFILESIZE 变量,您可以在自己的 Shell 启动文件中对它们进行设置。

通过 sort 来运行 history 非常有用,可以获得最常用的命令的列表。然后,使用 awk 删除命令名称减号选项和参数,然后将经过排序的列表传递给 uniq 以得到一个枚举列表。最后,再次调用 sort 以便对列表的第一列按照相反次序进行排序(最大的在前面),这是对其自身进行枚举。清单 2 显示了实际操作的示例。

清单 2. 根据使用频率列举 Shell 历史记录中的命令
$ history|awk '{print $2}'|awk 'BEGIN {FS="|"} {print $1}'|sort|uniq -c|sort -r

      4 ls
      2 cd
      1 who
$

如果历史记录文件比较大,您可以首先通过管道传输到 tail 来运行周期性的检查,例如,要检查最后的 1,000 条命令,可以尝试使用:

$ history|tail -1000|awk '{print $2}'|awk 'BEGIN {FS="|"} {print $1}'|sort|uniq -c|sort -r

查看访问或修改的文件

可以使用相同的原则来查看访问和修改过的文件。要完成这项工作,可以使用 find 实用程序来定位和查看在某一段时间内(今天、昨天或者过去的任何日期或时间段)访问或更改过的所有文件。

通常,您无法找出到底是 对文件进行了最后的访问或修改,因为在 UNIX 中不大容易获得这种信息,但通过将搜索限制为您的 home 目录树中包含的文件,您可以仅查看个人的文件。您还可以对搜索进行限制,以便仅搜索您正在监视或使用的特定项目目录中的文件。

find 实用程序有几个标志,可以用来根据时间定位文件,如表 1 中所列举的。目录不是常规文件,但是在列出目录内容或将其作为当前工作目录时,对其进行了访问,所以需要在搜索中使用否定和 -type 标志排除它们。

表 1. find 实用程序的一些标志
标志描述
-daystart这个标志表示从某天凌晨开始。
-atime最后访问该文件的时间,用天数表示。
-ctime最后更改该文件状态的时间,用天数表示。
-mtime最后修改该文件的时间,用天数表示。
-amin最后访问该文件的时间,用分钟数表示。(并不是在所有的实现中都可用。)
-cmin最后更改该文件状态的时间,用分钟数表示。(并不是在所有的实现中都可用。)
-mmin最后修改该文件的时间,用分钟数表示。(并不是在所有的实现中都可用。)
-type这个标志描述了文件的类型,如 d 表示目录。
-userX文件属于用户 X
-groupX文件属于组 X
-newerX文件比文件 X 更新。

下面介绍了如何列出您的 home 目录树中、在整整一个小时之前经过修改的所有的文件:

$ find ~ -mmin 60 \! -type d

为标志给定一个负值,表示要匹配该数值或更近的。例如,下面介绍了如何列出您的 home 目录树中、从一个小时之前到现在经过修改的所有的文件:

$ find ~ -mmin -60 \! -type d

并非所有的 find 实现都支持 min 标志。如果您的 find 不支持,那么您可以使用 touch 创建一个虚拟文件,它的时间戳比要找的文件早,然后使用 -newer 标志搜索比它更新的文件:

$ date
Mon Oct 23 09:42:42 EDT 2006
$ touch -t 10230842 temp
$ ls -l temp
-rw-r--r--    1 joe        joe               0 Oct 23 08:42 temp
$ find ~ -newer temp \! -type d

特殊的 -daystart 标志,当与任何日期选项一起使用时,可以度量从当天凌晨开始(而不是 24 小时以前)到命令执行的时刻。下面的命令尝试列举存在于系统中的任何位置、从当天凌晨到现在访问过的所有的文件:

$ find / -user `whoami` -daystart -atime -1 \! -type d

类似地,您可以列出 home 目录树中、今天修改 的所有文件:

$ find ~ -daystart -mtime -1 \! -type d

为各种时间标志赋于不同的值,可以更改搜索时间。您还可以对这些标志进行组合。例如,您可以列出 home 目录树中、从七天之前到现在经过访问 修改的所有的文件:

$ find ~ -daystart -atime -7 -mtime -7  \! -type d

您还可以根据特定日期或时间范围(以天或分钟进行度量)查找文件。要完成该任务,通常可以使用 touch 创建一个或多个虚拟文件,如前所述。

当您需要查找匹配某个范围的文件时,建立两个虚拟文件,它们的时间戳可以描述这个范围。然后,对较旧的文件使用 -newer 标志,对第二个文件使用“\! -newer”。

例如,要在 /usr/share 目录树中查找在 2006 年 8 月经过访问的所有文件,可以尝试下面的命令:

$ touch -d "Aug 1 2006" file.start
$ touch -d "Sep 1 2006" file.end
$ find /usr/share -daystart -newer file.start \! -daystart -newer file.end

最后,在列出目录内容时,可以按照文件的最后修改时间进行排序,这样做有时很有帮助。有些版本的 ls 工具具有 -c 选项,它可以按照文件修改的时间进行排序,最先显示最后修改的文件。与 -l长清单)和 -t(按照修改时间排序)选项一同使用,您可以对目录清单按照最后修改文件在前的顺序排序,长清单可以显示文件的修改时间而不是缺省创建时间:

$ ls -ltc /usr/local/proj/websphere | less

计算工作花费的时间

使用 UNIX 提高办公工作效率的另一种有价值的方式是,计算经常执行的命令所花费的时间。然后,您可以对结果进行评估,并确定是否花费了过多的时间等待一个特定的进程结束。

计算命令执行所花费的时间

系统是否运行迟缓?您在 Shell 中等待了多长时间,在某个特定命令执行时,什么也做不了?完成早上的日常工作需要花费多长时间呢?

当您使用 datesleepecho 命令来计算具体任务所花费的时间时,可以获得关于这些问题的实质性的解答。

要完成这项工作,可以输入一行以 date 语句开头的长输入行,以便按照需要的格式(通常,小时和分钟就足够了)输出时间和日期。然后,运行该命令输入行(可能是由 Shell 指令串联起来的几行内容),最后可以使用相同的输入行再次得到日期。如果您所测试的这些命令产生了大量的输出,可以对其进行重定向,以便能够阅读到开始和停止日期。计算这两个日期的差:

$ date; system-backup > /dev/null; system-diag > /dev/null;\
> netstat > /dev/null; df > /dev/null; date

测试您的打字速度

您可以使用相同的方法来测试打字输入:

$ date;cat|wc -w;date

如果您提供一个至少持续 1 分钟以上的输入示例,但最好是 3 分钟或更长的时间,那么该命令的结果将更准确。计算这两个日期之间的差(以分钟为单位),然后使用您所输入的单词数(由中间的命令输出)除以这个值,以得到平均每分钟输入的单词数。

通过为开始和停止日期以及输出单词数的命令设置相应的变量,您可以为这项任务实现自动化。但是为了正确地完成这项任务,您必须在使用这些时间做减法计算的时候避免一个常见的错误。GNU 对 date 命令进行了扩展,即 %s 格式选项,可以用来避免这样的错误,它输出自UNIX 新纪元 以来的秒数,该时间定义为 UTC 时间 1970 年 1 月 1 日凌晨。然后,您可以单独根据秒数来计算时间。

分配一个变量 SPEED 作为 echo 命令的输出,以便设置正确的公式通过管道传递给计算器工具,如 bc。然后,输出一个新的 echo 语言,该语句将输出关于打字速度的消息:

$ START=`date +%s`;WORDS=`cat|wc -w`; STOP=`date +%s`; SPEED=\
> `echo "$WORDS / ( ( $STOP - $START ) / 60 )"|bc`;echo \
> "You have a typing speed of $SPEED words per minute."

您可以将它放到一个脚本中,然后更改其权限,以使得所有的用户都可以执行它,以便系统中其他的用户也可以使用它,如清单 3 所示。

清单 3. 运行 typespeed 脚本的示例
$ typespeedThe quick brown fox jumped over the lazy dog. The quick brown dog--
                              ...
--jumped over the lazy fox.^D

You have a typing speed of 82.33333333 words per minute.
$

了解日期

date 工具可以完成更多的工作,不仅仅只是打印出当前的系统日期。您可以使用它来得到给定的日期究竟是星期几,并得到相对于当前日期的相对日期。

了解某一天是星期几

GNU 对 date 命令的另一个扩展是 -d 选项,当您的桌上没有日历表时(UNIX 用户不需要日历表),该选项非常有用。使用这个功能强大的选项,通过将日期作为引号括起来的参数提供,您可以快速地查明一个特定的日期究竟是星期几:

$ date -d "nov 22"
Wed Nov 22 00:00:00 EST 2006
$

在本示例中,您可以看到今年的 11 月 22 日是星期三。

所以,假设在 11 月 22 日召开一个重大的会议,您可以立即了解到这一天是星期三,而这一天您将赶到驻地办公室。

获得相对日期

-d 选项还可以告诉您,相对于 当前日期若干天的究竟是哪一天,从现在开始的若干天或若干星期以后,或者以前(过去)。通过将这个相对偏移使用引号括起来,作为 -d 选项的参数,就可以完成这项任务。

例如,您需要了解两星期以后的日期。如果您处于 Shell 提示符处,那么可以迅速地得到答案:

$ date -d '2 weeks'

关于使用该命令,还有其他一些重要的方法。使用 next 指令,您可以得到以后的星期几是哪一天:

$ date -d 'next monday'

使用 ago 指令,您可以得到过去的日期:

$ date -d '30 days ago'

您可以使用负数以得到相反的日期:

$ date -d 'dec 14 -2 weeks'

这个技巧非常有用,它可以根据将来的日期为自己设置提醒,可能是在脚本或 Shell 启动文件中,如下所示:

DAY=`date -d '2 weeks' +"%b %d"`
if test "`echo $DAY`" = "Aug 16"; then echo 'Product launch is now two weeks away!'; fi

为自己设置提醒

您可以在系统中使用各种工具为自己设置离开的提醒,与纸制便笺相比,它们占用更少的空间,并且无论您在任何地方登录都可以看到它们。

了解何时有事需要离开

当您在系统中进行工作时,很可能会碰到其他的事情。leave 工具在 IBM AIX® 操作系统和 Berkeley Software Distribution (BSD) 系统(请参见参考资料部分)中非常常见,并且可以为您提供帮助。

leave 命令指定需要离开的时间,使用 24 小时的格式:HHMM。它运行于后台,并将在给定时间之前的 5 分钟时,在终端中输出提醒您准备离开的信息。如果在离开前 1 分钟时,您依然处于登录状态,它会再次显示这个提醒消息,然后是在应该离开的时刻,并且在此之后每隔 1 分钟它都会发送提醒消息,直至您注销登录(或者终止这个 leave 进程)。清单 4 给出了一个示例。当您注销时,将终止这个 leave 进程。

清单 4. 运行 leave 命令的示例
$ leave
When do you have to leave? 1830
Alarm set for Fri Aug  4 18:30. (pid 1735)
$ date +"Time now: %l:%M%p"
Time now: 6:20PM
$
<system bell rings>
You have to leave in 5 minutes.
$ date +"Time now: %l:%M%p"
Time now: 6:25PM
$
<system bell rings>
Just one more minute!
$ date +"Time now: %l:%M%p"
Time now: 6:29PM
$
Time to leave!
$ date +"Time now: %l:%M%p"
Time now: 6:30PM
$
<system bell rings>
Time to leave!
$ date +"Time now: %l:%M%p"
Time now: 6:31PM
$ kill 1735
$ sleep 120; date +"Time now: %l:%M%p"
Time now: 6:33PM
$

您可以提供相对时间。如果您希望在从现在 开始的某个时间后离开,可以在时间参数前面加上 +。所以,要提醒在两小时后离开,可以输入下面的命令:

$ leave +0200

要以分钟为单位提供时间,可以让小时字段为 0。例如,如果您知道在 10 分钟之后必须离开,可以输入:

$ leave +0010

您还可以指定离开时间作为参数,这使得 leave 成为脚本中非常有用的命令,特别是在 Shell 启动文件中。例如,如果您通常工作到下午 5 点,但是在星期 5 时必须在下午 4 点离开单位,那么您可以在 Shell 启动文件中设置一个周提醒:

if test "`date +%a`" = "Fri"; then leave 1600; fi

您可以在启动脚本中加入一个简单的 leave 语句,不带任何参数。每次登录 Shell 时,您可以输入离开的时间,如果您按下 Enter 键,即没有指定任何值,那么 leave 将会退出,而不会设置提醒。

为自己发送电子邮件提醒

您还可以使用文本消息为自己发送提醒。建立一则提醒消息,有些时候非常有用,您将在当前登录会话或下次登录时了解到这一点。

以前,旧的 elm 邮件代理附带一个工具,它允许您使用电子邮件发送备忘录,实际上是提醒发送者的脚本、主题和正文文本。通过基于时间的方法,使用命令行 mailx 工具向自己发送邮件,可以轻松地复制这个过程。(在一些 UNIX 系统中,使用 mail 来代替 mailx。)

将您的电子邮件地址(或您在本地系统中的用户名,如果您在本地系统中读取邮件)作为参数提供,然后,您可以在提示的 Subject 行中输入提醒消息(如果它非常短),如清单 5 所示。如果提醒消息不适合于 Subject 行,那么可以在消息正文中输入它。单独一行 ^D,表示退出 mailx 并发送邮件。

清单 5. 使用 mailx 命令向自己发送提醒的示例
$ mailx joe
Subject: Call VP on Monday^D
Cc:
Null message body; hope that's ok
$

实现重复性交互工作的自动化

Expect 语言(是 Tcl/Tk 的扩展,还有其他的变种可供使用)用来编写与交互式程序运行会话的脚本,而该脚本就好像是一个用户,直接与程序进行交互。

Expect 脚本可以为您节省大量的时间,特别是当您发现自己正在进行重复性任务的时候。Expect 可以与多个程序进行交互,包括 Shell 和基于文本的 Web 浏览器,它可以启动远程会话,并通过网络进行执行。

例如,如果您需要频繁地连接到本地内部网中的系统,以运行特定的程序,比如 test-servers 命令,您可以使用一个名为 servmaint 的 Expect 脚本实现自动化,该脚本的内容如清单 6 所示。

清单 6. 使用 Expect 脚本实现远程系统程序执行的自动化的示例
#!/usr/bin/expect -f
spawn telnet webserv4
expect "login:"
send "joe\r"
expect "Password:"
send "secret\r"
expect "webserv4>$"
send "test-servers\r"
expect "webserv4>$"
send "bye\r"
expect eof

现在,对于整个执行过程,不再需要运行 telnet 连接到远程系统,使用您的用户名和密码进行登录,在该系统上运行这些命令,然后注销。您只需运行清单 6 中给出的 servmaint 脚本,就可以自动完成所有的工作。当然,如果您在这种脚本中提供了密码或其他专用的信息,那么就有一个安全性因素需要考虑,至少,您应该更改该文件的权限,以确保您是唯一可以读取它的用户(除超级用户之外)。

可以在 Expect 中对涉及到系统交互的重复性任务进行编程,它提供了分支、条件以及高级语言的所有其他特性,以便与这些程序交互的响应和方向能够完全实现自动化。


结束语

在办公环境中,UNIX 系统可以处理许多任务,而通常情况下,这些任务由运行其他操作系统的单独的计算机进行处理,使用 UNIX 系统中丰富的命令行工具,可以提高工作效率,而在任何其他的地方根本找不到这些工具。

本文介绍了一些使用 UNIX 命令行工具和应用程序来提高办公工作效率的技巧和概念。您可以将这些思想应用于自己的办公环境,灵活地使用命令行工具,可以提供更多的方式以节省时间并提高工作效率。

参考资料

学习

获得产品和技术

  • leave utility:如果您的 UNIX 系统中没有 leave 实用程序,您可以从 netbsd.org 下载免费的副本。
  • date tooldate 工具的 GNU Project 实现包含了输出从 UNIX 新纪元以来的秒数的扩展。从 GNU Project Web 站点下载免费的副本。
  • IBM 试用软件:使用 IBM 软件开发您的下一个项目,可直接从 developerWorks 下载这些试用软件。

讨论

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=AIX and UNIX
ArticleID=236382
ArticleTitle=UNIX 生产力技巧
publish-date=06252007