Thursday, February 26, 2009

028 显示用户连接的总计时长

ac命令用于显示用户连接系统的总计时长。
查看当前用户连接时长
选项–d 将按照天为单位显示用户的连接时间。在下面的例子中我今天已经登录系统6个小时了。在12月1日我登录了大约一个小时。
$ ac –d 

Dec 1 total 1.08
Dec 2 total 0.99
Dec 3 total 3.39
Dec 4 total 4.50
Today total 6.10

显示所有用户的登录时长
使用–p选项显示所有用户的登录时长。注意这里显示了不同用户累计的登录时间。
$ ac -p  

john 3.64
madison 0.06
sanjay 88.17
nisha 105.92
ramesh 111.42
total 309.21

显示某个指定用户的登录时长
要显示某个用户的登录时长,使用下面的命令。
$ ac -d sanjay 

Jul 2 total 12.85
Aug 25 total 5.05
Sep 3 total 1.03
Sep 4 total 5.37
Dec 24 total 8.15
Dec 29 total 1.42
Today total 2.95

027 diff 命令的使用

diff命令用于比较两个文件并显示他们之间不同的地方。显示结果可能是非常杂乱的并不易读。
语法: diff [选项] file1 file2

查看文件修改前后的不同
-w选项将忽略对空格的比较。
在以下的比较结果中:
  • ---上面显示内容是比较后第一个文件中的不同点(name_list.txt)。
  • ---下面显示内容是比较后第二个文件中的不同点(name_list_new.txt)。

# diff -w name_list.txt name_list_new.txt 

2c2,3
< John Doe
---
> John M Doe
> Jason Bourne

026 stat命令的使用

stat命令用于显示一个文件或者一个文件系统的状态/属性信息。
显示一个文件或者目录的统计信息

$ stat /etc/my.cnf  

File: `/etc/my.cnf'
Size: 346 Blocks: 16 IO Block: 4096 regular file
Device: 801h/2049d Inode: 279856 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid:
( 0/ root)
Access: 2009-01-01 02:58:30.000000000 -0800
Modify: 2006-06-01 20:42:27.000000000 -0700
Change: 2007-02-02 14:17:27.000000000 -0800

$ stat /home/ramesh

File: `/home/ramesh'
Size: 4096 Blocks: 8 IO Block:
4096 directory
Device: 803h/2051d Inode: 5521409 Links: 7
Access: (0755/drwxr-xr-x) Uid: ( 401/ramesh) Gid: (
401/ramesh)
Access: 2009-01-01 12:17:42.000000000 -0800
Modify: 2009-01-01 12:07:33.000000000 -0800
Change: 2009-01-09 12:07:33.000000000 -0800

使用-f 选项查看文件系统的状态
$ stat -f / 

File: "/"
ID: 0 Namelen: 255 Type: ext2/ext3
Blocks: Total: 2579457 Free: 2008027 Available:
1876998 Size: 4096
Inodes: Total: 1310720 Free: 1215892

025 cut命令的使用

你可以使用cut命令显示一个文件或者输出结果中的指定行。
以下是一些例子:
从一个以冒号分隔字段的文件中找出第一行(employee name)
 cut -d: -f 1 names.txt

Emma Thomas
Alex Jason
Madison Randy
Sanjay Gupta
Nisha Singh

显示文件的第一行和第三行
 cut -d: -f 1,3 names.txt

Emma Thomas:Marketing
Alex Jason:Sales
Madison Randy:Product Development
Sanjay Gupta:Support
Nisha Singh:Sales

只显示文件中每一行的前8个字符
 cut -c 1-8 names.txt

Emma Tho
Alex Jas
Madison
Sanjay G
Nisha Si

cut命令的混合使用
  • cut -d: -f1 /etc/passwd:显示系统中所有的用户名。
  • free | tr -s ' ' | sed '/^Mem/!d' | cut -d" " -f2:显示所有的可用内存。

024 uniq 命令的使用

uniq命令经常与sort命令结合使用,通过它可以将排序结果中重复的项目移除。
1.当你的employee文件中有重复的记录,你可以通过下面的命令将重复部分移除。

$ sort namesd.txt | uniq 

$ sort –u namesd.txt

2.如果你想知道有多少行是重复的,使用下面的命令。下面例子中的第一个字段显示查找到的重复记录的个数。所以在下面的文件中Alex 和Emma在names.txt文件中找个两个重复的。
$ sort namesd.txt | uniq –c 

2 Alex Jason:200:Sales
2 Emma Thomas:100:Marketing
1 Madison Randy:300:Product Development
1 Nisha Singh:500:Sales
1 Sanjay Gupta:400:Support

3.下面的命令只列出重复的记录
$ sort namesd.txt | uniq –cd 

2 Alex Jason:200:Sales
2 Emma Thomas:100:Marketing

023 排序命令

排序命令用于对一个文件中的每一行进行排序。我们有一个示例文件,下面的命令将基于这个文件对其中的内容进行排序。如下所示是这个文件的格式:
employee_name:employee_id:department_name.

 cat names.txt 

Emma Thomas:100:Marketing
Alex Jason:200:Sales
Madison Randy:300:Product Development
Sanjay Gupta:400:Support
Nisha Singh:500:Sales

按升序排列
 sort names.txt 

Alex Jason:200:Sales
Emma Thomas:100:Marketing
Madison Randy:300:Product Development
Nisha Singh:500:Sales
Sanjay Gupta:400:Support

按降序排列
 sort -r names.txt

Sanjay Gupta:400:Support
Nisha Singh:500:Sales
Madison Randy:300:Product Development
Emma Thomas:100:Marketing
Alex Jason:200:Sales

以一个以冒号(:)分隔字段的文件中的第二个字段进行(employee_id)
 sort -t: -k 2 names.txt 

Emma Thomas:100:Marketing
Alex Jason:200:Sales
Madison Randy:300:Product Development
Sanjay Gupta:400:Support
Nisha Singh:500:Sales

对文件中的第三个字段进行排序(department_name)并禁止对重复字段的显示
 sort -t: -u -k 3 names.txt

Emma Thomas:100:Marketing
Madison Randy:300:Product Development
Alex Jason:200:Sales
Sanjay Gupta:400:Support

对password文件的第三个字段进行排序(数字型的userid)
 sort -t: -k 3n /etc/passwd | more 

root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

按照ip地址对/etc/hosts 文件内容进行排序
 sort -t . -k 1,1n -k 2,2n -k 3,3n -k 4,4n /etc/hosts

127.0.0.1 localhost.localdomain localhost
192.168.100.101 dev-db.thegeekstuff.com dev-db
192.168.100.102 prod-db.thegeekstuff.com prod-db
192.168.101.20 dev-web.thegeekstuff.com dev-web
192.168.101.21 prod-web.thegeekstuff.com prod-web

结合其他命令使用sort命令
  • ps –ef | sort :对过程处理结果进行排序
  • ls -al | sort +4n :按照文件的大小升序排列。比如有5个文件,尺寸最小的排在最上面。
  • ls -al | sort +4nr :按照文件的大小升序排列。比如有5个文件,尺寸最大的排在最上面。

022 Xargs 命令

xargs是一个非常强大的命令,它可以将一个命令的输出结果作为参数传给另一个命令。下面是一些如何有效利用xargs命令的例子。
1.当你想使用rm命令删除很多文件时,你可能会得到一个异常消息:bin/rm Argument list too long – Linux。我们可以使用xargs命令来避免错误的发生。
find ~ -name '*.log' -print0 | xargs -0 rm -f

2.列出/etc/下所有的*.conf文件。有很多中方法可以得到我们想要的结果,下面只列出了使用xargs的方式。find命令的结果通过xargs命令被作为ls -l的参数。
# find /etc -name "*.conf" | xargs ls –l

3.如果你有一个文件,其中包含了你想要下载的URLs,你可以使用下面的命令:
# cat url-list.txt | xargs wget –c

4.查找所有的jpg文件并把它们打包
# find / -name *.jpg -type f -print | xargs tar -cvzf 
images.tar.gz

5.将所有的图片文件复制到一个外部的硬件驱动器上
# ls *.jpg | xargs -n1 -i cp {} /external-hard-
drive/directory

021 大小写转换

将一个文件的所有内容转换为大写:
 cat employee.txt 

100 Jason Smith
200 John Doe
300 Sanjay Gupta
400 Ashok Sharma

tr a-z A-Z < employee.txt

100 JASON SMITH
200 JOHN DOE
300 SANJAY GUPTA
400 ASHOK SHARMA


将一个文件的内容转换为小写
 cat department.txt 

100 FINANCE
200 MARKETING
300 PRODUCT DEVELOPMENT
400 SALES

tr A-Z a-z < department.txt

100 finance
200 marketing
300 product development
400 sales

Tuesday, February 24, 2009

020 join 命令

join命令用于通过一个公共字段将两个文件合并。比如在下面的例子中我们有两个文件employee.txt 和salary.txt。这两个文件的公共字段是员工号,所以在这里我们可以通过join命令按照员工号将两个文件合并成一个文件。
先看看原来两个文件的内容:
 cat employee.txt

100 Jason Smith
200 John Doe
300 Sanjay Gupta
400 Ashok Sharma

cat bonus.txt

100 $5,000
200 $500
300 $3,000
400 $1,250

下面是合并后的内容:
# join employee.txt bonus.txt 

100 Jason Smith $5,000
200 John Doe $500
300 Sanjay Gupta $3,000
400 Ashok Sharma $1,250

019 禁止标准输出和错误消息的输出

有时候在调试shell脚本的时候,你可能即不想看到标准输出也不想看到错误消息。下面例子中的/dev/null可以禁止这些输出。
使用>/dev/null禁止标准输出
如果你不想看到echo输出而只想看到错误消息的时候,这个命令在你调试shell脚本的时候非常有用:

# cat file.txt > /dev/null 

# ./shell-script.sh > /dev/null

使用2> /dev/null 禁止错误消息的输出
这个命令同样有用,如果你只希望看到标准输出而不希望看到错误消息:
# cat invalid-file-name.txt 2> /dev/null 

# ./shell-script.sh 2> /dev/null

018 find命令

find命令用于根据不同的条件在UNIX文件系统中查找文件。我们将通过多个例子来学习如何使用这个命令。

语法: find [pathnames] [conditions]

如何查找文件名中包含特定字符的文件
下面的例子将查找/etc命令下文件名中包含mail字符串的文件:
# find /etc -name "*mail*"

如何查找文件尺寸大于某个值的文件
下面的命令将列出系统中尺寸大于100M的文件:
# find / -type f -size +100M

如何查找文件的修改日期距今超过指定天数的文件
下面的命令将列出当前目录下所有60天前被修改的文件:
# find . -mtime +60

如何查找文件的修改日期在距今某个指定的天数内的文件
下面的命令将列出最近2天内修改的文件:
# find . –mtime -2

如何查找所有以*.tar.gz结尾并且文件尺寸超过100M的文件
请小心使用下面的命令以免删除掉你不想删除的文件。最好的方法是加上一个ls -l命令确保删除的时候你知道哪些文件要被删除,然后再加上rm命令来删除这些文件:
# find / -type f -name *.tar.gz -size +100M -exec ls -l {} \;

# find / -type f -name *.tar.gz -size +100M -exec rm -f {} \;

如何将指定天数内没有被修改的文件打包成归档文件
下面的命令将会把/home/jsmith下60天内没有被修改的文件创建成一个ddmmyyyy_archive.tar归档文件并放到/tmp目录下:


提示:你可以使用midnight commander GUI来处理很多跟文件操作相关的任务,这是一个功能强大的基于文本的文件管理工具。

017 grep 命令的使用

Linux中grep命令用于从文件中查找一个特定的文本。这个功能强大的命令有多个选项:
Syntax: grep [options] pattern [files]

如何查找文件中有多少行包含指定的关键字
在下面的例子中grep命令将查找/etc/password 文件中所有包含John的行:
# grep John /etc/passwd

jsmith:x:1082:1082:John Smith:/home/jsmith:/bin/bash
jdoe:x:1083:1083:John Doe:/home/jdoe:/bin/bash
如果给这个命令加上-v 参数将显示除了匹配行以外的其他行,下面的例子中将查找/etc/passwod文件中所有不包含John字符串的行。注意,在这个文件中有很多行都不匹配这个文本我们这里只显示了第一行:
# grep -v John /etc/passwd

jbourne:x:1084:1084:Jason Bourne:/home/jbourne:/bin/bash
查找文件中有多少行匹配某个特定的文本
下面的例子中将显示/etc/password文件中匹配文本John的行数:

# grep -c John /etc/passwd
2

你也可以通过设置-cv来查找文本中不匹配某个特定字符串的行数:
# grep -cv John /etc/passwd
39

如何在查找文本时忽略文本内容的大小写
给grep命令加上-i参数将忽略文本内容的大小写:
# grep -i john /etc/passwd

jsmith:x:1082:1082:John Smith:/home/jsmith:/bin/bash
jdoe:x:1083:1083:John Doe:/home/jdoe:/bin/bash

如何在目录下所有的子目录中查找匹配特定文本的文件
我们可以通过-r(recursive递归的意思)来实现。下面的例子中将查找/home/users/目录以及子目录下所有包含John文本的文件,并且忽略其大小写。
执行下面的命令后将显示文件名:匹配查找内容的行。你也可以加上一个-l参数,这样就只显示文件名称。
# grep -ri john /home/users

/home/users/subdir1/letter.txt:John, Thanks for your
contribution.
/home/users/name_list.txt:John Smith
/home/users/name_list.txt:John Doe

# grep -ril john /root

/home/users/subdir1/letter.txt
/home/users/name_list.txt

Monday, February 23, 2009

016 查看SSH会话的统计信息

要想获得一些有用的有关当前会话的统计信息可以使用下面的命令,注意这个命令只在SSH2中支持:
1.登录到远程主机
localhost ssh -l jsmith remotehost

2.在远程主机输入ssh转义字符~加上s参数可以查看当前会话的统计信息
remotehost  [注意: ~s 是不会再你的命令行上显示的] 

remote host: remotehost
local host: localhost
remote version: SSH-1.99-OpenSSH_3.9p1
local version: SSH-2.0-3.2.9.1 SSH Secure
Shell (non-commercial)
compressed bytes in: 1506
uncompressed bytes in: 1622
compressed bytes out: 4997
uncompressed bytes out: 5118
packets in: 15
packets out: 24
rekeys: 0
Algorithms:
Chosen key exchange algorithm: diffie-hellman-
group1-sha1
Chosen host key algorithm: ssh-dss
Common host key algorithms: ssh-dss,ssh-rsa
Algorithms client to server:
Cipher: aes128-cbc
MAC: hmac-sha1
Compression: zlib
Algorithms server to client:
Cipher: aes128-cbc
MAC: hmac-sha1
Compression: zlib

localhost$

015 通过转移符号在SSH会话之间切换

在你连接到远程主机后,你可能希望回到本机执行一些任务然后再回到远程主机上。在这种情况下你不必断开与远程主机的连接,按照下面的步骤就可以:
1.从本机登录到远程主机
localhost$ ssh -l jsmith remotehost

2.现在你已经连接到远程主机
remotehost$

3.要回到本机的会话中,你需要键入转移符号~并按下Control-Z
你输入~之后必须按下Control-Z并回车才能看到本机的界面,所以在远程主机上你应该在新的一行中输入下面的命令:
remotehost$ ~^Z 
[1]+ Stopped ssh -l jsmith remotehost

localhost$

4.现在你已经返回到了本机会话中而远程主机会话会当作一个UNIX后台任务运行,你可以通过下面的命令验证一下:
localhost$ jobs 
[1]+ Stopped ssh -l jsmith remotehost

5.无需输入密码你就可以直接返回到远程主机上,这个过程只是把后台任务调到前台执行:
localhost$ fg %1 
ssh -l jsmith remotehost

remotehost$

014 调试SSH客户端会话

有时候我们需要打印调试信息来查找SSH客户端出现的问题。将参数-v(小写的v)传给ssh命令就可以显示调试信息。
以下是不包含调试信息的例子:
localhost$ ssh -l jsmith remotehost.example.com 

warning: Connecting to remotehost.example.com failed:
No address associated to the name

以下是包含调试信息的例子:


locaclhost$ ssh -v -l jsmith remotehost.example.com

debug:
SshConfig/sshconfig.c:2838/ssh2_parse_config_ext:
Metaconfig parsing stopped at line 3.

debug:
SshConfig/sshconfig.c:637/ssh_config_set_param_verbose:
Setting variable 'VerboseMode’ to 'FALSE’.

debug:
SshConfig/sshconfig.c:3130/ssh_config_read_file_ext:
Read 17 params from config file.

debug: Ssh2/ssh2.c:1707/main: User config file not
found, using defaults. (Looked for
'/home/jsmith/.ssh2/ssh2_config’)

debug: Connecting to remotehost.example.com, port 22…
(SOCKS not used)
warning: Connecting to remotehost.example.com failed:
No address associated to the name

0013 使用SSH登录远程主机

当你第一次从本地登录远程主机的时候,系统会显示一个无法找到主机密匙的消息,你回答yes就可以继续了。主机密匙文件保存在你的根目录下的.ssh2/hostkeys 文件夹下,如下所示:
localhost ssh -l jsmith remotehost.example.com

Host key not found from database.
Key fingerprint:
xabie-dezbc-manud-bartd-satsy-limit-nexiu-jambl-title-jarde-
tuxum
You can get a public key’s fingerprint by running
% ssh-keygen -F publickey.pub
on the keyfile.
Are you sure you want to continue connecting (yes/no)? Yes

Host key saved to
/home/jsmith/.ssh2/hostkeys/key_22_remotehost.example.com.pu
host key for remotehost.example.com, accepted by jsmith Mon
May 26 2008 16:06:50 -0700
jsmith@remotehost.example.com password:

remotehost.example.com$

下次你再登录的时候就只需要提供登录密码就可以了,因为主机密匙已经保存在SSH客户端中了:
localhost ssh -l jsmith remotehost.example.com
jsmith@remotehost.example.com password:

remotehost.example.com$

如果由于某些原因,在你第一次登陆远程主机后,主机上的密匙文件变更了,你可能会得到类似下面的警告消息。这可能是因为以下的原因:
  • 系统管理员更新/重新安装了主机上的SSH服务端。
  • 某些人进行了恶意攻击。
在你对某些命令回答"yes"之前,你最好问问你的系统管理员为什么你会得到这个警告消息或者他是不是更改了密匙文件。


localhost ssh -l jsmith remotehost.example.com    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@  @       WARNING: HOST IDENTIFICATION HAS CHANGED!         @  @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@  IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!  Someone could be eavesdropping on you right now (man-in-the- middle attack)!  It is also possible that the host key has just been changed.  Please contact your system administrator.  Add correct host key to  “/home/jsmith/.ssh2/hostkeys/key_22_remotehost.example.com.pu b”  to get rid of this message.  Received server key’s fingerprint:  xabie-dezbc-manud-bartd-satsy-limit-nexiu-jambl-title-arde- tuxum  You can get a public key’s fingerprint by running  % ssh-keygen -F publickey.pub  on the keyfile.  Agent forwarding is disabled to avoid attacks by corrupted  servers.  Are you sure you want to continue connecting (yes/no)? yes    Do you want to change the host key on disk (yes/no)? yes    Agent forwarding re-enabled.  Host key saved to  /home/jsmith/.ssh2/hostkeys/key_22_remotehost.example.com.pub  host key for remotehost.example.com, accepted by jsmith Mon  May 26 2008 16:17:31 -0700    jsmith @remotehost.example.com’s password:     remotehost$ 

如何用minidom解析xml

在实际的项目中我们可能要解析xml配置文件来设置系统的属性,Python中的xml处理功能非常强大而且简单,使用Python来处理xml非常简单,举个例子,假设我们有一个xml文件如下:
<database>
<table name='product'>
<field name='P_name' type='string'/>
<field name='P_brand' type='string'/>
<field name='P_price' type='number'/>
<field name='P_unit' type='string'/>
</table>
<table name='part'>
<field name='P_name' type='string'/>
<field name='P_platform' type='string'/>
<field name='P_weight' type='number'/>
<field name='P_volume' type='number'/>
</table>
</database>

现在我们想把这个database中所有的table的内容都打印出来,或者我们想找出所有字段名为p_name的字段,使用python的minidom包可以非常简单的完成:
from xml.dom.minidom import parse
import re
dom=parse("config.xml")
for table in dom.getElementsByTagName('table'):
tableName=field.getAttributeNode('name').nodeValue
for field in field.getElementsByTagName('field'):
name=style.getAttributeNode('name').nodeValue
type=style.getAttributeNode('type').nodeValue
if re.search('p_name',name):
print tableName,',',name,',',type


我们来一行行的解释一下上面的代码:
首先我们需要导入parse解析器,这是用来解析xml文档的模块,它位于xml.dom.minidom下。为了查找字段名为p_name的表我们需要使用正则表达式,通过import re来导入Python中的正则表达式。
接着dom=parse("config.xml")
用来将我们要解析的xml文件加载进来。getElementsByTagName方法用来查找这个xml中元素节点名为table的节点,getAttributeNode方法是查找这个元素的一个属性,其中后面的nodeValue是一个节点的通用属性,你可以在元素或者属性对象上调用这个方法来获得这个节点的文本值。
之后就是在查找到的元素或者属性集合中循环,然后通过re.search()方法查找匹配条件的节点并打印他们的内容。
怎么样是不是很简单,整个代码只有11行却完成了我们想要的功能。

012 识别SSH客户端版本

有时候我们可能想知道当前的SSH客户端的版本号是多少,可以使用ssh -V 命令查看。记住,Linux使用的是OpenSSH。
下面的命令显示了某个Linux系统使用的SSH版本:
 ssh -V
OpenSSH_3.9p1, OpenSSL 0.9.7a Feb 19 2003
下面命令显示这个操作系统使用的是SSH2的客户端:


$ ssh -V 
ssh: SSH Secure Shell 3.2.9.1 (non-commercial version)
on i686-pc-linux-gnu

011 显示将来的日期和时间

下面的命令可以显示将来的日期和时间:
$ date 
Thu Jan 1 08:30:07 PST 2009

$ date --date='3 seconds'
Thu Jan 1 08:30:12 PST 2009

$ date --date='4 hours'
Thu Jan 1 12:30:17 PST 2009

$ date --date='tomorrow'
Fri Jan 2 08:30:25 PST 2009

$ date --date="1 day"
Fri Jan 2 08:30:31 PST 2009

$ date --date="1 days"
Fri Jan 2 08:30:38 PST 2009

$ date --date="2 days"
Sat Jan 3 08:30:43 PST 2009

$ date --date='1 month'
Sun Feb 1 08:30:48 PST 2009

$ date --date='1 week'
Thu Jan 8 08:30:53 PST 2009
$ date --date="2 months"
Sun Mar 1 08:30:58 PST 2009

$ date --date="2 years"
Sat Jan 1 08:31:03 PST 2011

$ date --date="next day"
Fri Jan 2 08:31:10 PST 2009

$ date --date="-1 days ago"
Fri Jan 2 08:31:15 PST 2009

$ date --date="this Wednesday"
Wed Jan 7 00:00:00 PST 2009

010 显示以前的日期和时间

下面的命令可以显示以前的日期和时间:
$ date --date='3 seconds ago' 
Thu Jan 1 08:27:00 PST 2009

$ date --date="1 day ago"
Wed Dec 31 08:27:13 PST 2008

$ date --date="1 days ago"
Wed Dec 31 08:27:18 PST 2008

$ date --date="1 month ago"
Mon Dec 1 08:27:23 PST 2008

$ date --date="1 year ago"
Tue Jan 1 08:27:28 PST 2008

$ date --date="yesterday"
Wed Dec 31 08:27:34 PST 2008

$ date --date="10 months 2 day ago"
Thu Feb 28 08:27:41 PST 2008

Sunday, February 22, 2009

009 以指定的格式显示当前的日期和时间

以下列示了如何以不同的格式显示当前的日期和时间:
 date
Thu Jan 1 08:19:23 PST 2009

date --date="now"
Thu Jan 1 08:20:05 PST 2009

date --date="today"
Thu Jan 1 08:20:12 PST 2009

date --date='1970-01-01 00:00:01 UTC +5 hours' +%s
18001

date '+Current Date: %m/%d/%y%nCurrent Time:%H:%M:%S'
Current Date: 01/01/09
Current Time:08:21:41

date +"%d-%m-%Y"
01-01-2009

date +"%d/%m/%Y"
01/01/2009

date +"%A,%B %d %Y"
Thursday,January 01 2009

你可以通过给date命令传递不同的参数来显示不同格式的日期:
  • %D 日期格式(mm/dd/yy)
  • %d 一个月中的每一天 (01..31)
  • %m 显示月份 (01..12)
  • %y 显示年份的后两位 (00..99)
  • %a 显示本地格式的一个星期中的每一天的名字(简写格式) (Sun..Sat)
  • %A 显示本地格式的一个星期中的每一天的名字(全称格式) (Sunday..Saturday)
  • %b 本地化的月份的简写(Jan..Dec)
  • %B 本地化的月份的全称(January..December)
  • %H 显示24小时制的小时(00..23)
  • %I 显示12小时制的小时(01..12)
  • %Y 显示年份(全部四位)(1970…)

008 设置硬件时间

在设置硬件的日期和时间时,请确保你已经按照我们前面第7节讲的那样正确的设置了系统的时间。根据系统日期设置硬件日期的命令如下:
# hwclock –systohc

# hwclock --systohc –utc


使用hwclock命令不加任何参数可以查看当前的硬件日期和时间。

# hwclock

你可以打开时钟文件看看当前系统是否设置为UTC(格林威治时间)
# cat /etc/sysconfig/clock

ZONE="America/Los_Angeles"
UTC=false
ARC=false

Tuesday, February 17, 2009

007 设置系统日期和时间

要设置系统日期使用下面的命令:
# date {mmddhhmiyyyy.ss}
  • mm – 月份
  • dd – 天
  • hh – 24小时格式的小时
  • mi – 分钟
  • yyyy – 年
  • ss – 秒

假设你想将时间按设置为:2009年1月31日下午10:19:53,你可以这样:
# date 013122192009.53

你还可以想下面这样通过提供参数的方式设置日期:
# date 013122192009.53

# date +%Y%m%d -s "20090131"

# date -s "01/31/2009 22:19:53"

# date -s "31 JAN 2009 22:19:53"

# date set="31 JAN 2009 22:19:53"

或者只设置时间:
# date +%T -s "22:19:53"
# date +%T%p -s "10:19:53PM"

006 通过“shopt -s cdspell”命令自动更正cd 命令中的拼写错误

我们可以通过“shopt -s cdspell”命令自动更正cd 命令中的拼写错误。如果你的拼写能力很糟糕这个命令会对你有所帮助:

# cd /etc/mall
-bash: cd: /etc/mall: No such file or directory

# shopt -s cdspell

# cd /etc/mall

# pwd
/etc/mail

[注意:由于拼写错误,我把mail写成了mall,这里cd自动更正了这个错误。]

005 使用dirs,pushd和popd维护目录堆栈

你可以使用“目录堆栈”将一个目录加入到这个堆栈中,随后你可以把它从堆栈中取出来。以下三个命令会被用到:
  • dirs:显示当前目录堆栈中的内容。
  • pushd:将一个目录添加到这个堆栈中。
  • popd:将一个目录从这个堆栈中取出来然后进入到这个目录中。
dirs命令总是打印当前目录堆栈中的内容,如果这个堆栈为空,那么就打印当前的目录。如下所示:

# popd
-bash: popd: directory stack empty

# dirs
~

# pwd
/home/ramesh




那么如何使用pushd和popd命令呢,让我们先创建一些临时目录并把它们加入到当前的目录堆栈中:
# mkdir /tmp/dir1
# mkdir /tmp/dir2
# mkdir /tmp/dir3
# mkdir /tmp/dir4

# cd /tmp/dir1
# pushd .

# cd /tmp/dir2
# pushd .

# cd /tmp/dir3
# pushd .

# cd /tmp/dir4
# pushd .

# dirs
/tmp/dir4 /tmp/dir4 /tmp/dir3 /tmp/dir2 /tmp/dir1

[注意:这里的的第一个目录 (/tmp/dir4) 永远是当前的目录]

现在我们的目录堆栈中包含以下四个目录:
/tmp/dir4
/tmp/dir3
/tmp/dir2
/tmp/dir1

最后一个加入到堆栈中的目录在这个列表的最上面。所以当你执行popd命令时将会导航到/tmp/dir4 目录下同时这个目录会从堆栈中移除:
# popd
# pwd
/tmp/dir4

[注意:执行上面的命令后,目录堆栈中的内容为:
/tmp/dir3
/tmp/dir2
/tmp/dir1]


# popd
# pwd
/tmp/dir3

[注意:执行上面的命令后,目录堆栈中的内容为:
/tmp/dir2
/tmp/dir1]


# popd

# pwd
/tmp/dir2

[注意:执行上面的命令后,目录堆栈中的内容为:
/tmp/dir1]

# popd
# pwd
/tmp/dir1

[注意:执行上面的命令后,目录堆栈中的内容为空]

# popd
-bash: popd: directory stack empty

004 通过cd- 在最后访问的两个目录之间切换

你可以像下面的例子中那样通过cd- 命令在最后浏览的两个目录之间切换:

# cd /tmp/very/long/directory/structure/that/is/too/deep

# cd /tmp/subdir1/subdir2/subdir3

# cd -

# pwd
/tmp/very/long/directory/structure/that/is/too/deep


# cd -

# pwd
/tmp/subdir1/subdir2/subdir3

# cd -

# pwd
/tmp/very/long/directory/structure/that/is/too/deep

003 通过一个命令执行mkdir和cd命令

有时候你可能需要在创建了一个新的目录后直接导航到这个新创建的目录下,像下面例子中这样:


# mkdir -p /tmp/subdir1/subdir2/subdir3

# cd /tmp/subdir1/subdir2/subdir3

# pwd
/tmp/subdir1/subdir2/subdir3

把这两步操作放在一起执行不是很好吗?你只需要把下面的代码加入到.bash_profile文件中就可以了:
 vi .bash_profile

function mkdircd () { mkdir -p "$@" && eval cd
"\"\$$#\""; }

现在你就可以通过一条命令执行mkdir和cd命令了:
# mkdircd /tmp/subdir1/subdir2/subdir3

[注意:现在你可以在创建一个目录后自动导航到这个目录下]

# pwd
/tmp/subdir1/subdir2/subdir3

002 给cd命令创建别名,提高目录导航的效率

当你在一个非常长的路径中导航的时候,根据你方法的目录层次数,你不得不重复多次使用cd ..\..\ 中的..\符号来导航到你要去的目录,这真的很麻烦,比如下面这样:

# mkdir -p
/tmp/very/long/directory/structure/that/is/too/deep

# cd /tmp/very/long/directory/structure/that/is/too/deep

# pwd
/tmp/very/long/directory/structure/that/is/too/deep

# cd ../../../../

# pwd
/tmp/very/long/directory/structure
除了使用cd ../../../.. 命令导航到当前目录上面四层的目录,你还可以使用以下之一的方法:
方法一:使用“..n”来导航到上层目录
在下面的例子中你可以使用..4来导航到当前目录以上四层的目录下,以此类推..3可以导航到上三层目录,..2可以导航到上两层目录,方法是在~/.bash_profile文件中创建下面的别名:

alias ..="cd .."
alias ..2="cd ../.."
alias ..3="cd ../../.."
alias ..4="cd ../../../.."
alias ..5="cd ../../../../.."

# cd
/tmp/very/long/directory/structure/that/is/too/deep

# ..4
[注意我们这里使用..4来导航到上面四层目录中]

# pwd
/tmp/very/long/directory/structure/


方法二:只适用点号(.)来向上导航
在下面的例子中你可以使用.....(五个点号)来导航到上四层目录,这种方式非常好记,当你输入两个点号..时表示向上导航一层目录,以此类推每增加一个点号就是多导航一层目录。所以,如果输入....(四个点号)就是向上导航三层目录。你可以通过把下面的内容加入~/.bash_profile文件中实现这样的操作:


alias ..="cd .."
alias ...="cd ../.."
alias ....="cd ../../.."
alias .....="cd ../../../.."
alias ......="cd ../../../../.."

# cd /tmp/very/long/directory/structure/that/is/too/deep

# .....
[注意:我们这里使用了.....(五个点号)向上导航了4层目录]

# pwd
/tmp/very/long/directory/structure/


方法三:通过在cd后加上连续的点号向上层目录导航
在下面的例子中通过cd.....(cd后面加五个点号)可以导航到上四层目录中。这种方式也便于记忆。当你在cd后加两个点号,代表向上导航一层目录,每增加一个点号就是向上导航一级目录,所以cd....(cd后加四个点)表示向上导航三层目录,cd...(cd后加三个点)表示向上导航两层目录,你只要将下面的别名加入~/.bash_profile就可以实现了:
alias cd..="cd .."
alias cd...="cd ../.."
alias cd....="cd ../../.."
alias cd.....="cd ../../../.."
alias cd......="cd ../../../../.."

# cd /tmp/very/long/directory/structure/that/is/too/deep

# cd.....
[注意:这里使用cd.....导航到上四层目录]

# pwd
/tmp/very/long/directory/structure


方法四:直接在cd后加数字来导航
下面的例子中cd4代表向上导航4层目录:


alias cd1="cd .."
alias cd2="cd ../.."
alias cd3="cd ../../.."
alias cd4="cd ../../../.."
alias cd5="cd ../../../../.."

Monday, February 16, 2009

001 通过CDPATH来设置cd 命令的根目录

如果你使用cd命令来跳转到某个“父目录”下的“子目录”时,你可以通过CDPATH来设置这个父目录,而不必每次都输入完整的路径。

[ramesh@dev-db ~]# pwd
/home/ramesh

[ramesh@dev-db ~]# cd mail
-bash: cd: mail: No such file or directory

[注意:上面的命令是在当前路径下查找mail子目录]

[ramesh@dev-db ~]# export CDPATH=/etc
[ramesh@dev-db ~]# cd mail
/etc/mail

[注意:现在我们查找的是etc目录下的mail子目录]

[ramesh@dev-db /etc/mail]# pwd
/etc/mail

当然目前的CDPATH只作用于当前的会话,如果你要使之永久生效,你需要将CDPATH=/etc 加入到~/.bash_profile 中,和设置PATH变量类似,你可以在CDPATH中定义多个路径,不同的路径之间用冒号(:)隔开:
export CDPATH=.:~:/etc:/var
这一技巧在下列情况中非常有用:
  • Oracle DBA 经常需要在 $ORACLE_HOME路径下工作,所以在CDPATH中设置Oracle的根目录就非常方便了。
  • Unix管理员经常在/etc目录下工作,所以将/etc添加到CDPATH就方便多了。
  • 开发人员经常在/home/projects目录下工作,所以我们也可以把它加到CDPATH中。
  • 普通用户经常在其用户文件目录下工作,所以可以在CDPATH中增加~ (代表当前用户文件目录)目录。