Monthly Archives: October 2008

输入输出重定向

Linux I/O Redirection Updated June 01, 2005 Created October 11, 2001

术语:stdout(标准输出),stdin(标准输入),stderr(标准错误)。
(此文档主要解释输入输出重定向(< >),管道(|)和tee命令的使用。)

命令示例

以下命令将stdout和和stderr分别保存到文件”out.txt”和”err.txt”中。

[kyle@server]$ ./cmd 1>out.txt 2>err.txt

以下命令将stdout和和stderr分别添加到文件”out.txt”和”err.txt”中。

[kyle@server]$ ./cmd 1>>out.txt 2>>err.txt

以下命令跟前两个命令相似,但会分别复制一份stdout和和stderr到文件”stdout.txt”和”stderr.txt”。

[kyle@server]$ (((./cmd | tee stdout.txt) 3>&1 1>&2 2>&3
> |tee stderr.txt) 3>&1 1>&2 2>&3) 1>out.txt 2>err.txt

Note:反斜杠()表示下行继续。当一行太长影响排版时,可以这样处理。

* Tar命令示例

[kyle@server]$ (cd /var/ftp/pub/rh71prof/disk1.iso.dir 
> && tar -cvf - .) | (cd /var/ftp/pub/rh71prof/i386 && tar -xvf -)

* Find命令示例-在每个文件里搜索指定字符串

[kyle@server]$ find . -type f -exec grep -i 
> searchstring {} --with-filename ;

注:-i表示-ignore-case,不分大小写。–with-filename可以用-H代替。{}前的两个反斜杠非必须。

* 测试脚本示例

#!/bin/sh
# 你可以用这个示例脚本测试。echo语句解释脚本是怎样工作的。
echo "This is Standard Out" >&1
echo "This is Standard Error" >&2

* for循环的stdout和stderr示例

#/bin/sh
echo Standard Out >stdout.txt
echo Standard Error >stderr.txt
for X in bzImage modules modules_install; do
    make $X;
done 1>>stdout.txt 2>>stderr.txt

* Linux的重定向

0 = 标准输入(stdin)
1 = 标准输出(stdout)
2 = 标准错误(stderr)

* 用tee命令将stdout保存到tee.txt文件,stdout同时显示到屏幕上。

[kyle@server]$ cmd | tee tee.txt

* 用tee命令将stdout添加到tee.txt文件,stdout同时显示到屏幕上。

[kyle@server]$ cmd | tee -a tee.txt

* 用script命令同时捕获stderr和stdout。

[kyle@server stdout]$ script
Script started, file is typescript
[kyle@server stdout]$ ./cmd
This is Standard Out
This is Standard Error
[kyle@server stdout]$ exit
exit
Script done, file is typescript
[kyle@server stdout]$ cat typescript 
Script started on Thu Oct 11 11:47:36 2001
[kyle@server stdout]$ ./cmd
This is Standard Out
This is Standard Error
[kyle@server stdout]$ exit
exit
 
Script done on Thu Oct 11 11:47:39 2001
[kyle@server stdout]$

* 关于管道(pipe,|)

  1. 把它想像成一个stdout或stderr的通道。
  2. pipe只能有一个通道,也就是stdout。
  3. 当你在命令中用到pipe时,stderr显示到屏幕上,而stdout发送到pipe,等待其他命令把它用做输入。
  4. 交换stdout和stderr后,会让stdout显示到屏幕,而stderr发送到pipe里。
  5. pipe自己只会接收stdout。如果你在使用pipe前,交换了stdout和stderr,那么pipe就会接收交换后的stdout(也就是stderr)。
  6. stdout和stderr可以合并起来发送到pipe里。但是,这样会让你无法区分stdout和stderr。
  7. 在子shell(subshell)”()”中使用pipe,会让stdout发送到pipe里,而stderr显示屏幕上。一般来说,你可以从子shell中把stdout和stderr都获取出来。

* 重定向的顺序
o 方法一

[kyle@server]$ cmd 2>&1 1>outfile.txt

#以上命令让stderr重定向到stdout,而原来的stdout则重定向到outfile.txt。
#注意,在fd(file descriptor,文件描述符)2被重定义时,fd 1仍然指向stdout。fd 2会继续指向stdout,不管fd1后来改变了什么。基本上,fd 2只是复制了fd 1指向的地址。

o 方法二
#以下命令把stdout和stderr都重定向至outfile.txt。

[kyle@server]$ cmd 1>outfile.txt 2>&1

#注意,stdout(1)重定向到outfile.txt,而2被重定义到1,两个通道合并了。

用Tee捕捉stderr,交换stderr和stdout

命令

[kyle@server]$ (((./cmd | tee stdout.txt) 3>&1 1>&2 2>&3 
| tee stderr.txt) 3>&1 1>&2 2>&3) 1>out.txt 2>err.txt

解释

以下部分将详细解释这个长命令。当你了解了它的原理后,你将能很容易地把它重新写出来。

1. ./cmd 脚本的内容

#!/bin/sh
# 你可以用这个示例脚本测试。echo语句解释脚本是怎样工作的。
echo "This is Standard Out" >&1
echo "This is Standard Error" >&2

2. ./cmd 脚本运行的结果

[kyle@server]$ ./cmd
This is Standard Out
This is Standard Error
[kyle@server]$

虽然两行都显示在屏幕上,但其实它们一行是stdout,另一行是stderr。假如使用管道的话,只有stdout会输出到管道里来。

3. 捕获 stdout
以下命令会复制一份stdout到文件stdout.txt。

[kyle@server]$ ./cmd | tee stdout.txt

stdout输出到管道里,tee将其复制一份保存到stdou.txt文件里。但,这里我们失去了对stderr的控制。stderr不会输出到管道,而是直接输出到屏幕上。

4. 同时控制stderr和stdout
通过用括号把命令括起来,我们取得了对stderr的控制。

[kyle@server]$ (./cmd | tee stdout.txt)

5. 交换stdout和stderr。
我们已经可以保存stdout了,现在我们想用tee把stderr也保存起来。管道只接受stdout的输入,所以我们必须交换stderr和stdout来达到我们的目的。

注意:交换使用了标准的变量交换方式——需要用到3个变量来使2个变量完成互换。(你有两个变量,你要交换它们的内容,必须用到一个临时变量来辅助。)

[kyle@server]$ (./cmd | tee stdout.txt) 3>&1 1>&2 2>&3

6. 捕获stderr
现在我们交换了stdout和stderr,来加上tee命令。tee现在可以捕获stderr了(tee相信那就是stdout,因为stdout是唯一能输出到管道里的东西)。

[kyle@server]$ (./cmd | tee stdout.txt) 3>&1 1>&2 2>&3 
> | tee stderr.txt

7. 再次同时控制stderr和stdout
tee捕获了stderr,但stdout又直接输出到屏幕上去了。让我们再次用括号来同时控制stderr和stdout。

[kyle@server]$ ((./cmd | tee stdout.txt) 3>&1 1>&2 2>&3 
> | tee stderr.txt)

8. 把stdou和stderr换回去
现在我们再次把stderr和stdout都捕获了。目前它们是互换过了的。让我们把它们换回去。再次使用标准交换方法。

[kyle@server]$ ((./cmd | tee stdout.txt) 3>&1 1>&2 2>&3 
> | tee stderr.txt) 3>&1 1>&2 2>&3

9. 第三次同时控制stderr和stdout
现在我们已经把stdout和stderr换回去了。但如果我们还想对stdout和stderr做进一步的操作,必须加上一个管道或另一对括号。

这里我们使用括号。用括号可以同时控制stdout和stderr。而用管道只能控制stdout。

注意:如果我们用一个管道或加一对括号,接下来的命令能恰当地区分stderr和stdout。如果不加括号,不要管道,stderr和stdout的顺序就仍是混乱的。

[kyle@server]$ (((./cmd | tee stdout.txt) 3>&1 1>&2 2>&3 
> | tee stderr.txt) 3>&1 1>&2 2>&3)

10. 把stdout和stderr重定向到不同的文件里
现在我们来做些什么,以证明stdout和stderr真的被换回到原来的位置上了。我们让命令把stdout重定向到out文件,stderr重定向到err文件。

[kyle@server]$ (((./cmd | tee stdout.txt) 3>&1 1>&2 2>&3 
> | tee stderr.txt) 3>&1 1>&2 2>&3) 1>out.txt 2>err.txt

注意out和err文件的内容跟运行以下命令的内容相同。这证明我们把stdout和stderr换回到它们原来的位置上了。以上命令让我们可以用tee复制一份stdout和stderr保存到文件里,同时它们还像往常发挥功能。

 [kyle@server]$ ./cmd 1>out.txt 2>err.txt

在一个文件里保存stderr,另一个文件里保存stderr和stdout
我想把stderr保存到一个文件里,stderr和stdout合并保存到另一个文件里,可以这样:

这是我们的让stderr和stdout定向到合适的通道里的测试命令:

kyle@server:~> (echo out >&1; echo err >&2)
out
err

这是能工作的命令:

kyle@server:~> (((echo out >&1; echo err >&2) 3>&2 2>&1 1>&3 | 
tee stderr.txt ) 3>&2 2>&1 1>&3 ) > combined.txt 2>&1
kyle@server:~> cat stderr.txt
err
kyle@server:~> cat combined.txt
out
err

其他资料

http://www.cpqlinux.com/jobcontrol.html
bash 手册:man bash

/myprog.sh 的内容

#!/bin/bash
echo "Standard Out" >&1
echo "Standard Error" >&2

把stdout保存到stdout.log,stderr保存到stderr.log,然后把它们都显示到屏幕上:

((( ./myprog.sh | tee stdout.log ) 3>&2 2>&1 1>&3 | tee stderr.log ) 3>&2 2>&1 1>&3 )

最后把stdout和stderr换回来,只是为了方便对它们的进一步操作。

把stdout保存到stdou.log,stderr保存到stderr.log,然后把stdout和stderr合并保存到combined.log,最后把它们显示到屏幕上:

((( ./myprog.sh | tee stdout.log ) 3>&2 2>&1 1>&3 | tee stderr.log ) 3>&2 2>&1 1>&3 ) 2>&1 | tee combined.log

原文:http://www.cpqlinux.com/redirect.html

1 Comment

使用find命令

搜索文件

find最简单的应用,是搜索当前目录及其子目录下的文件。

$ find .
./tp1301.txt
./up1301.txt
./tp1302.txt
./up1302.txt
./Up1303.txt
./misc/uploads
./misc/uploads/patch12_13.diff

像往常一样,那个点(.)代表当前目录。在以上例子里,find列出了当前目录及其子目录下的所有文件。

如果只想搜索up开头的文件名,使用’-name’参数。

也就是如下命令:

$ find . -name up*
./up1301.txt
./up1302.txt
./misc/uploads

find默认是大小写敏感的。如果想让find找到’p1303.txt’文件,要么使用’find -name UP*’,要么就用’iname’参数代替’name’参数。

通配符前的斜线是转义符,这样Bash才会把字面意义的星号传递给find作为参数,而不是首先把文件名扩展,再将扩展之后的那些文件名传递给find作为参数。

这个技巧很重要。要注意那些在shell里有特殊意义的字符。

我们也可以列出当前目录中以大小写不敏感的up(up, Up, uP, UP)开头,其中非小写up的文件名。

$ find -iname up* -not -name up*

操作符

find使用-and,-or,和-not参数支持布尔代数值。它们也可以分别缩写成-a,-o和!(在bash中必须使用!进行转义)。或(and)操作符在此提及,只是内容完整的需要。它是默认就在使用的:

$ find . -iname david*gray*ogg -type f > david_gray.m3u

上例中的操作符将按如下顺序处理:

() 圆括号 用圆括号强制执行顺序提前。

-not 反转测试表达式的结果。

-and 如ex1 -and ex2;如果第一个表达式为假,将不再执行第二个表达式。

-or 如ex1 -or ex2;如果第一个表达式为真,将不再执行第二个表达式。

‘,’ 这是列表操作符(list operator)。不像-and和-or,它将使两个表达式都执行。在‘2 into 1 does go’部分有更多信息。

之前的那个例子将创建一个m3u播放列表,列出所有的以’David Gray’开头的ogg文件。(大小写不敏感)

$ find . -iname david gray*ogg -type f > david_gray.m3u

这个例子则将找出所有叫”david gray…ogg”的文件,照样大小写不敏感。

下例在语义上与上例等同:

$ find . -iname david gray*ogg -and -type f > david_gray.m3u

下例与上两例的语义等同:

$ find . -iname "david gray*ogg" -and -type f david_gray.m3u

如果艺术家’David Gray’的名字有可能在文件名里,也有可能在子目录名里,怎样找到它们呢?

$ find . -ipath *david gray*ogg -type f > david_gray.m3u

表达式以星号通配符开头,因为可能有不止一个的叫’david gray’的子目录仅仅是为了分类的符号链接。(GNU find中此语句必须以*开头,是因为不这样的话,就没有结果。并且-type f代表的是普通文件,-type l才是符号链接。所以,不知道作者说的什么意思。并且GNU find反对使用-ipath参数,应当使用的是-iwholename。)

这有另一个例子,我们将列出humour目录的内容(一行一个文件),然后搜索有大小写不敏感的’yodo’在文件名中的.mp3文件。

$ ls -l humour
Weird Al - Yoda.mp3
welcome_to_the_internet_helpdesk.mp3
werid al - livin' la vida yoda.mp3
$ find -ipath *humour*yoda* -type f
./humour/Weird Al - Yoda.mp3
./humour/werid al - livin' la vida yoda.mp3

合并任务

在操作符一节就已经暗示了,可以用find一次执行多次任务。

下例创建两个列表文件,一个包括所有的.php文件,另一个包括所有.js文件。-fprint参数表示把搜索结果输出到文件中。

$ find ~ -type f ( -name *.php -fprint php_files , -name *.js -fprint javascript_files )

剪切

假设您想创建一个播放列表文件列出所有David Gray的.ogg文件,但是有些专辑你不想包括在内。

您可以用-prune参数阻止这些专辑出现在播放列表中,-prune参数匹配不包含某个表达式的目录或文件名。

下例能将Flesh和Lost Songs专辑排除:

$ find ( -path ./mp3/David_Gray/Flesh* -o -path "./mp3/David_Gray/Lost Songs" * ) 
-prune -o -ipath *david gray*

首先,您会注意到被转义的圆括号,这样bash才不会误用它们。使用-prune参数,意思就是”别找这些,去找其他的“。

$ find (-path <don't want this> -o -path <don't want this too >;)
-prune -o -path <global expression for what I do want>

可能需要较长的时间才能掌握-prune参数的使用:首先要确定你究竟想使用它做什么。我发现使用-prune参数能省下不少时间让我去完成其他任务。

其他参数

还有许多其他表达式和参数可供find使用。

这有一些可能是您最想使用的:

-nouser 拥有文件的用户不在/etc/passwd文件中。

-nogroup 拥有文件的组不在/etc/groups文件中。

-owner 指定用户拥有的文件。

我们将在稍后再研究这些参数以及其他一些参数的使用。

输出方式

改变输出信息

如果您输出的不仅仅是文件名,-printf参数可以输出任何种类你想要的信息。去看看手册页,那里有惊人多的选项。

以下这些可能是使用最多的:

%p 文件名,名字中包括其所在的目录,也即是路径名(path)。
%m 文件的权限,以数字显示。
%f 文件名,不包括所在目录。
%g 文件所属组名。
%h 显示文件所在目录。
%u 文件所属用户名。

如下例:

$ find . -name *.ogg -printf %f

将生成一个包含所有当前目录及其子目录想的.ogg文件列表。

‘ ‘前的反斜线很重要,’ ‘代表开始新一行。’n'之前的反斜线必须被转义,否则命令行解释器将会首先使用’ ‘。

输出到哪里

find有一些参数控制输出信息写入到任何您想写入的文件。它们使-fprint,-fprint0,-fprintf参数。

$ find . -iname david gray*ogg -type f -fprint david_gray.m3u

这样,上例比下例更有效。

$ find . -iname david gray*ogg -type f > david_gray.m3u

执行命令

文件是生成基本信息报告的很好工具,但是如果你想要的不仅仅是报告呢?你可以把标准输出用管道重定向给其他工具。

$ find ~/oggs/ -iname *.mp3 | xargs rm

不过,这并不总是那么有效。

最好还是使用-exec参数。

$ find ~/oggs/ -iname *.mp3 -exec rm {} ;

也许这个例子比较难看懂,它的意思是搜索到这些文件后便立即将其删除。

‘{}’是一个代表找到的所有文件的占位符,’;'必须被转义,以免bash误用。

谨慎起见,-ok参数可以代替-exec。-ok参数会在执行命令之前请就确认。

这有许多种方法可以用到日常真实情况中。

比如,你的默认Mozilla配置文件被锁定了,下例可以帮你解锁。(删除lock文件即可)

$ find ~/.mozilla -name lock -exec rm {} ;

压缩当前及其子目录下所有日志文件:

$ find . -name *.log -exec bzip {} ;

将当前及其子目录下所有无有效用户权限的文件的权限赋予给用户ken。

$ find . -nouser -exec chown ken {} ;

用vim打开所有当前目录下的.dat文件,不搜索子目录。

$ vim -R `find . -name *.dat -maxdepth 1`

在当前目录中至少四层以下(包括四层)的子目录中搜索目录名CVS。

$ find -mindepth 4 -type d -name CVS

创建时间

也许您想搜索最近创建的文件,或者查找近三天内的日志文件中的字符串。

这是find所擅长的:它可以根据文件的时间戳来限制搜索的范围。

假设您想找到您主目录中近五天内修改过的隐藏文件:

$ find ~ -mtime -5 -name .*

如果你知道某个文件在更近的时间内修改过,例如14分钟内,可用如下参数:

$ find ~ -mmin -14 -name .*

注意,列出文件(ls)的操作会影响文件的访问时间戳。如果你先做一次列出文件(ls)的操作,然后再使用上例中的命令,所有的文件都会列出。(不知道作者用的是什么版本的find。GNU find 4.32是区别amin(access)和mmin(modify)的,上例仍有效)

要找到那些在某个时间点之后修改过的文件,可以使用下例中的技巧:

$ touch -d "13 may 2001 17:54:19" date_marker
$ find . -newer date_marker

要找到创建于上例中时间点之前的文件,使用’cnewer’加否定式:

$ find . ! -cnewer date_marker

找出昨天里修改过的文件:

$ find . -daystart -atime 1 -maxdepth

‘-daystart’参数意思是时间从今天的开端(也即今日之零点)开始计算,而不是从当前时间点开始计算。

这个参数只对’-amin’、’-atime’、’-cmin’、’ctime’、’mmin’和’mtime’选项有效。

文件大小

字符文件

要找出有含有指定数量字符的文件,您能错过这节。

找出有正好有1000个字符的文件:

$ find . -size 1000c

找出有600到700个字符的文件,600和700包含在内:

$ find . -size +599c -and -size -701c

字符(character)其实是误称:’c'在find中是字节(byte)意思;所以这些命令只能作用于ASII文件,对Unicode文件无用。

参考用户手册,我们可以看到:

c = 字节 bytes
w = 2字节 2 byte words
k = 千字节 kilobytes
b = 512字节的块 512-byte blocks

这样我们可以用find来找出指定大小的文件:

$ find /usr/bin -size 48k

空文件

你可以用下例找到空文件:

$ find . -size 0c

用-empty参数更有效。

删除当前目录下所有空文件:

$ find . -empty -maxdepth 1 -exec rm {} ;

用户和组

用户

搜索属于指定用户的文件:

$ find /etc -type f !  -user root -exec ls -l {} ;
-rw------- 1 lp sys 19731 2002-08-23 15:04 /etc/cups/cupsd.conf
-rw------- 1 lp sys    97 2002-07-26 23:38 /etc/cups/printers.conf

如果只需要上面列出信息的子集的话,就没必要使用exec:

root@ttyp0[etc]$ find /etc -type f !  -user root -printf "%h/%f %u"
/etc/cups/cupsd.conf lp
/etc/cups/printers.conf lp

如果您只知道用户id(uid),而不知道用户名的话,可以用’-uid’参数:

$ find /usr/local/htdocs/www.linux.ie/ -uid 401

‘-nouser’参数意思是所有在/etc/passwd文件中的用户都不拥有所要搜索的文件。

也可以搜索属于或不属于指定组的文件,取决您如何使用它。

这非常适合用来搜索那些本该属于www组,但却不属于的文件:

$ find /www/ilug/htdocs/  -type f ! -group  www

‘-nogroup’参数意思是所有在/etc/group文件中的组都不拥有所要搜索的文件。

如果某个组使用过一段时间后被删除了,这个参数就有用了。

用’gid’参数搜索属于指定gid的文件。

$ find -gid 100

权限

如果您曾经因为权限设置问题而无法运行一些脚本,并且您想一次性解决这个问题,那您应该看下面这个小例子:

knoppix@ttyp1[bin]$ ls -l ~/bin/
total 8
-rwxr-xr-x    1 knoppix  knoppix        21 2004-01-20 21:42 wl
-rw-r--r--    1 knoppix  knoppix        21 2004-01-20 21:47 ww
 
knoppix@ttyp1[bin]$ find ~/bin/ -maxdepth 1 -perm 644 -type f -not -name .*
/home/knoppix/bin/ww

找出所有没有执行权限(644)的文件,就像我们在输出中看到的。

文件类型

‘-type’参数明显是用来指定寻找什么类型的文件的(记住,在Linux下,一切东西都是某种文件)。

目前为止,我用过’-type f’来寻找普通文件。

如果我们想找到有’_of_’在其文件名中的目录,可以用:

$ find . -type d -name '*_of_*'

上例中的输出不会包括指向目录的符号链接。

如果想包括目录和指向目录的符号链接,请用:

$ find . ( -type d -or -type l ) -name '*_of_*'

参考用户手册,以获得所有文件类型的完成列表。

正则表达式

我们已经偶尔使用过通配符来指定一组文件。find也支持正则表达式,所以我们也可以使用更复杂的规则来指定要搜索的文件。正则表达式会以整个路径为匹配对象:

ken@gemmell:/home/library/src$ find . -regex '.*/mp[0-4].*'
./library/sql/mp3_genre_types.sql

‘-regex’的大小写不敏感的形式是’-iregex’。

使用正则表达式的技巧是:注意匹配的是文件的绝对路径,即使是在搜索当前文件文件夹。如:

$ cd /usr/share/doc/samba-doc/htmldocs/using_samba
$ find . -regex './ch0[1-2]_0[1-3].*'
./ch01_01.html
./ch01_02.html
./ch02_01.html
./ch02_02.html
./ch02_03.html

文件系统

使用root用户将一个微软格式的软盘挂载起来做一个实验:

$ su -
$ mount /floppy
$ mount
/dev/sda2 on / type ext2 (rw,errors=remount-ro)
proc on /proc type proc (rw)
devpts on /dev/pts type devpts (rw,gid=5,mode=620)
/dev/fd0 on /floppy type msdos (rw,noexec,nosuid,nodev)

然后试如下命令:

$ find / -fstype msdos -maxdepth 1

您应该只看到/floppy列出来。

要得到想反的结果,比如列出不在msdos文件系统上的文件,可用:

$ find / -maxdepth 1 ( -fstype msdos ) -prune -or -print

这只是对指定文件系统来搜索文件的一个简单介绍。

总结

我已经介绍了非常多的find工具的功能,但这并不是全部。如果您有任何问题,不要犹豫,您可以给我发邮件。

原文:http://www.linux.ie/newusers/beginners-linux-guide/find.php

作者信息:http://www.linux.ie/whoswho/ken_guest

Leave a comment

Xargs示例教程

Xargs示例教程

目录

  • 1 示例
    • 1.1 使用占位符
    • 1.2 转换多行为一个参数
    • 1.3 自定义分隔符
    • 1.4 从文件读取输入
    • 1.5 显示将被执行的命令
    • 1.6 处理有空格的路径名
  • 2 一段代码

示例

使用占位符

Code: 列出所有目录

find . -maxdepth 1 -type d -print | xargs echo Directories:

将输出当前文件夹下的所有目录。echo命令将从find命令输出里读取输入并执行一次。这段代码将输出所有目录在一行上。

Code: 用-I列出所有目录

find . -maxdepth 1 -type d -print | xargs -I {} echo Directory: {}

这次给xargs加了替换参数-I {}。这个参数让xargs把后面一个{}替换成find的每一行输出。所以这次会每行输出一个目录。{}即是占位符。

Note: 如果xargs -I出现错误,你需要升级你的xargs了。Gentoo的findutils包里包含有xargs。

记住,使用xargs来写稍微复杂点的命令时,你经常需要用到-I参数。如,你想运行几个命令,或运用类似管道的功能。

转换多行为一个参数

Code:

ls | xargs -L 4 echo

使用-L参数,可以连接多行到一行(当然,以空格隔开)。这段代码将输出每行四个文件或目录名。

自定义分隔符

Code: 以逗号为分隔符

echo “foo,bar,baz” | xargs -d, -L 1 echo

-d参数用来自定义分隔符,支持c语言风格的转义(escaping),如n表示换行。这段代码将输出foo,bar和baz,一行显示一个。

从文件读取输入

Code:

xargs -a foo -d, -L 1 echo

-a参数使xargs从文件中读取输入。除此之外,这个段代码跟上一段代码相同。

显示将被执行的命令

Code:

ls | xargs -t -L 4 echo

-t选项让xargs在执行命令前显示命令到标准输出。

处理有空格的路径名

Code:

find . -print0 | xargs -0 echo

find输出的每个参数都以null字符结束,而不是默认的空格。这个功能很少用到。但是,当你碰到包含了空格、退格或换行的路径名时,它就很有用了。

一段代码

Code: 递归删除当前目录下的.svn目录

find . -type d -name “.svn” -print | xargs rm -rf

以上命令,将删除find找到的每个.svn目录。当需要针对多个文件执行命令时,可使用类似以上范例的结构。这跟find的-exec参数的功能类似,但能避免出现参数太多(Too Many Arguments)的错误提示。并且,在大多数情况下,xargs比-exec更有效。

原文:http://sidvind.com/wiki/Xargs_by_example

Leave a comment

my Firefox addons

Firefox没装插件时,还不是一个好用的浏览器。装了我喜欢的插件后,就强大到无话可说了。

近来在Windows下比较喜欢用Chrome,简单快速。我大部分时间在Linux下干活,Chrome没有Linux版本是个缺憾。

以下插件都是我曾经用过或目前在用的,不定期更新:

Delicious Bookmarks:用惯了Delicious后,再也没用过firefox自己的Bookmarks功能了。只是Bookmars Toolbar还在用。
TwitterFox:主要用来接收别人twitter消息,我更新不多。
rtmgmail:在Gmail里管理todolist。懒得再去打开一次rtm,而Gmail是我每日必开的。主要是还没学会高效地使用rtm,所以不喜欢去rtm主页。

Web Developer:就如它的名字,web开发者必备。
Firebug:调试web页面工具。同样是web开发者必备。
YSlow :这是插件firebug的插件,插件的插件。分析网站前端性能的工具,根据hpws的14条rules。
Greasemonkey:这个插件非常强大。要是懂点javascript编程,能更好地利用它。

FoxyProxy:代理切换。
ShwoIP:显示网站ip。
QuikcDrag:drag a link。

Google:Google的两个插件当然必装,虽然其实我不怎么用。

Hide Menubar :隐藏菜单栏,alt健显示。

FireFTP:在Firefox里使用ftp。

ScribeFire Blog Editor:在Firefox里写blog。

It’s All Text!:在自己喜欢的编辑器,Emacs或Vim里编辑表单文本。
Firemacs:让Firefox有跟Emacs类似的快捷键。
Vimperator:让firefox用起来像vim一样。我不大喜欢用鼠标,这个插件必备。

主题。我习惯往bookmarks toolbar里加一些常去网站的favicon,所以我对主题的唯一要求就是要紧凑点,每个favicon不要隔太远就好。常用的有:Noia 2.0 (eXtreme)Classic Compact

还有我的Emacs elisp,还有我的Vim plugins。加上wordpress和firefox的,都可以成为一个系列了。这些插件系列,得要长期维护。

往后再不用Google Docs来更新Wordpress了,添加了太多无用HTML代码。所见即所得编辑就是这样,冗余导码过多,我还是更喜欢所想即所得的概念。往后都在Wordpress后台编辑器的HTML模式下从事更新工作吧,也好写完就加分类和标签。

revision 1: Oct 16, 2008
revision 2: Dec 23, 2008. vimperator

Leave a comment

my WordPress plugins

WordPress目前有3,098插件。不知道比起Firefox谁的多些。我想Firefox应该多很多很多,不过我没找到确切的数字。哪天也要写篇我的Firefox插件,这应该是每个blogger的家庭作业的。

曾用过和在用的插件:
Different Posts Per Page:我用这个插件,是因为我想在首页显示1篇文章,而在其他页里显示10篇文章。
Google XML Sitemaps:这个插件有利于blog更好地被Google索引。我禁止百度索引我的blog。
WP-Syntax:这个插件用来给代码高亮效果,支持很多语言。效果见此。对于喜欢写点小代码的人,此插件不可或缺。用的是GeSHi高亮引擎,支持我知道的几乎任何语言。
WP-PageNavi:加页码。
Batch Categories:批量操作分类。
WordPress Related Posts:显示相关文章。但在我这里基本都是显示一些随机文章。
Akismet插件:默认就有了的,用来过滤垃圾评论。我的评论基本没有,暂时不需启用它。

wp-db-backup:定期将数据库备份发到邮箱,这个不能少。
disable revisions and autosave:revison功能只会多占数据库空间,没有实用价值。autosave,也没什么大意义。

关于blog的URL,以前我一直觉得用%postname%比较好看。后来发现还是直接用数字比较方便,不要费心去起英文标题或者写英文slug了。现在我的URL是类似www.xlau.org/post/177这样的形式,打算固定下来,不再改变了。

revision 1: Oct 11, 2008
revision 2: Dec 23, 2008. GeSHi, wp-db-backup, disable-revisions-and-autosave.

Leave a comment

清空文件

Why?

1 If an active process has the file open(like log files), removing afile and creating a new one will not affect the logging program; those messages will just keep going to the file that’s no longer linked.

2 When you remove a file and create a new one with the same name, the new file will have your default permissions and ownership.

3 Completely empty files don’t take any space to store.

4 You can use the empty files as “place markers” to remind you that something was there or belongs there.

5 Empty files hold a “timestamp” that shows when the file was last modified.

How?

1 $ > afile       # and then C-d
2 $ cat /dev/null > afile
3 $ cp /dev/null > afile
4 # not really empty
$ tail afile > tmpfile
$ cat tmpfile > afile
$ rm tmpfile
5 $ sed -i 'd' afile

From Unix Power Tools

前四种都用到了重定向,第五种是我加的,用sed删。Google Docs的post to blog功能有点古怪,比如这篇文章我从gDocs里我死活就发不出来。可能是太多英文的原因吧,也可能是太多代码的原因吧,反正我是找不到原因。

2 Comments

No ie6

我昨天花时间改的模板,在ff3,chrome和ie7里都工作正常,但rico同学说它是支离破碎的。当然是他的问题,什么年代了,还有人用ie6吗?

想了想解决办法,要改下模板去支持ie6呢,还是干脆block ie6 。我选择后者。no ie6

两个js文件,一个图像文件,用到了js库jqurey。安装非常容易,加两行代码到head里去就行了。

我用IETester 测试ie6 blocker 的安装。

把ie6 blocker去掉了。不能为了block ie6而拖慢整个blog的加载速度呀。

1 Comment