存档在 ‘每日一脚本’ 分类

shell之xargs

2013年9月16日

xargs 的功能
在使用find命令的-exec选项处理匹配到的文件时, find命令将所有匹配到的文件一起传递给exec执行。但有些系统对能够传递给exec的命令长度有限制,这样在find命令运行几分钟之后,就会出现溢出错误。错误信息通常是“参数列太长”或“参数列溢出”。
这就是xargs命令的用处所在,特别是与find命令一起使用。find命令把匹配到的文件传递给xargs命令,而xargs命令每次只获取一部分文件而不是全部,不像-exec选项那样。这样它可以先处理最先获取的一部分文件,然后是下一批,并如此继续下去。在有些系统中,使用-exec选项会为处理每一个匹配到的文件而发起一个相应的进程,并非将匹配到的文件全部作为参数一次执行;这样在有些情况下就会出现进程过多,系统性能下降的问题,因而效率不高;而使用xargs命令则只有一个进程。另外,在使用xargs命令时,究竟是一次获取所有的参数,还是分批取得参数,以及每一次获取参数的数目都会根据该命令的选项及系统内核中相应的可调参数来确定。

来看看xargs命令是如何同find命令一起使用的,并给出一些例子。
下面的例子查找系统中的每一个普通文件,然后使用xargs命令来测试它们分别属于哪类文件

 find . -type f -print | xargs file

在整个系统中查找内存信息转储文件(core dump) ,然后把结果保存到/tmp/core.log 文件中:

find . -name "*.core" -print | xargs echo "" > /mnt/liyao.log

在当前目录下查找所有用户具有读、写和执行权限的文件,并收回相应的写权限:

 ll
total 56
-rwxrwxrwx 1 root root  1012 Jul  3 21:43 anaconda-ks.cfg
-rwxrwxrwx 1 root root 27974 Jul  3 21:43 install.log
-rwxrwxrwx 1 root root  4708 Jul  3 21:43 install.log.syslog
-rwxrwxrwx 1 root root   232 Jul  3 22:36 liyao.txt

find . -perm -7 -print | xargs chmod o-w

 ll
total 56
-rwxrwxr-x 1 root root  1012 Jul  3 21:43 anaconda-ks.cfg
-rwxrwxr-x 1 root root 27974 Jul  3 21:43 install.log
-rwxrwxr-x 1 root root  4708 Jul  3 21:43 install.log.syslog
-rwxrwxr-x 1 root root   232 Jul  3 22:36 liyao.txt

用grep命令在所有的普通文件中搜索hostname这个词:

find . -type f -print | xargs grep "hostname"

用grep命令在 / 下的所有普通文件中搜索hostnames这个词:

find / -name \* -type f -print | xargs grep "hostnames"
Binary file /var/lib/rpm/Packages matches
Binary file /sbin/mount.nfs4 matches
Binary file /sbin/busybox matches
Binary file /sbin/nash matches
Binary file /sbin/dhclient matches
Binary file /sbin/mount.nfs matches
Binary file /sbin/umount.nfs4 matches
Binary file /sbin/umount.nfs matches

注意,在上面的例子中, \用来取消find命令中的*在shell中的特殊含义。

find命令配合使用exec和xargs可以使用户对所匹配到的文件执行几乎所有的命令。

 

一些重要的选项:

-t #显示当前执行的实际命令
-n #比如-n2 意思是每次传递给执行命名的源记录为两条

如何在shell脚本中屏蔽某些信号中断(ctrl+c/ctrl+d等)

2013年9月16日

可以使用trap命令,来捕获信号,常见信号有
HUP(1) 挂起,通常因终端掉线或用户退出而引发
INT(2) 中断,通常因按下Ctrl+C组合键而引发
QUIT(3) 退出,通常因按下Ctrl+\组合键而引发
ABRT(6) 中止,通常因某些严重的执行错误而引发
ALRM(14) 报警,通常用来处理超时
TERM(15) 终止,通常在系统关机时发送
还可以通过

kill -l

或者

trap -l

来打印

[root@Creater]#kill -l
 1) SIGHUP	 2) SIGINT	 3) SIGQUIT	 4) SIGILL	 5) SIGTRAP
 6) SIGABRT	 7) SIGBUS	 8) SIGFPE	 9) SIGKILL	10) SIGUSR1
11) SIGSEGV	12) SIGUSR2	13) SIGPIPE	14) SIGALRM	15) SIGTERM
16) SIGSTKFLT	17) SIGCHLD	18) SIGCONT	19) SIGSTOP	20) SIGTSTP
21) SIGTTIN	22) SIGTTOU	23) SIGURG	24) SIGXCPU	25) SIGXFSZ
26) SIGVTALRM	27) SIGPROF	28) SIGWINCH	29) SIGIO	30) SIGPWR
31) SIGSYS	34) SIGRTMIN	35) SIGRTMIN+1	36) SIGRTMIN+2	37) SIGRTMIN+3
38) SIGRTMIN+4	39) SIGRTMIN+5	40) SIGRTMIN+6	41) SIGRTMIN+7	42) SIGRTMIN+8
43) SIGRTMIN+9	44) SIGRTMIN+10	45) SIGRTMIN+11	46) SIGRTMIN+12	47) SIGRTMIN+13
48) SIGRTMIN+14	49) SIGRTMIN+15	50) SIGRTMAX-14	51) SIGRTMAX-13	52) SIGRTMAX-12
53) SIGRTMAX-11	54) SIGRTMAX-10	55) SIGRTMAX-9	56) SIGRTMAX-8	57) SIGRTMAX-7
58) SIGRTMAX-6	59) SIGRTMAX-5	60) SIGRTMAX-4	61) SIGRTMAX-3	62) SIGRTMAX-2
63) SIGRTMAX-1	64) SIGRTMAX	

比如我们要对以下的几个信号捕获且打印信息。

trap "echo "Receive a signal"" HUP INT PIPE QUIT TERM

shell 数组的使用

2013年8月16日

数组赋值方式:
(1) array=(var1 var2 var3 … varN)
(2) array=([0]=var1 [1]=var2 [2]=var3 … [n]=varN)
(3) array[0]=var1
arrya[1]=var2

array[n]=varN

(4) 部分赋值

array=(“1”  “2” [10]=”3″ “4” “5”)其中对array[0] array[1],array[10],array[11],array[12]进行了赋值。
计算数组元素个数或者长度:

(1) ${#array[@]}
(2) ${#array[*]}

了解了数组基础语法,举例说明,请看:

#!/bin/bash
NAMESERVERS=(“ns1.www.net.” “ns2.www.net.” “ns3.www.net.”)
# 得到数组长度
tLen=${#NAMESERVERS[@]}

# 循环数组
for (( i=0; i<${tLen}; i++ ));
do
echo ${NAMESERVERS[$i]}
done

在看一个复杂一点的例子,将文件内容读取到数组中:

#!/bin/bash

# 设置IFS将分割符 设置为 换行符(\n)
OLDIFS=$IFS
IFS=$’\n’

# 读取文件内容到数组
fileArray=($(cat file.txt))

# restore it
IFS=$OLDIFS
tLen=${#fileArray[@]}

# 循环显示文件内容
for (( i=0; i<${tLen}; i++ ));
do
echo “${fileArray[$i]}”
done

[每日一脚本]显示文件的绝对路径2013-09-15

2013年8月15日

很多时候需要显示某个指定目录下所有文件的绝对路径,比如需要对文件重命名。通常使用ll,ls达不到这一效果,还是得用find。

find /root -type f -name "*.txt" -exec ls  {} \;

比如上边例子,在root目录下查找所有txt结尾的文件,并显示其绝对路径。

[每日一脚本]分离文件目录与文件名2013-09-12

2013年8月12日

将绝对路径表示的文件,将其所在目录与文件名分离出来。

#!/bin/bash
awk ' BEGIN {
	fullName="/etc/system/myDir/myfile";
	if(match(fullName, /\/.*\//))
		dirName=substr(fullName, RSTART, RLENGTH)
	else
		print "文件路径错误或者不包含文件名"
	# print match(fullName, fullName)
	gsub(dirName,"", fullName)
	print "文件所在目录为:"dirName
	print "文件名为:"fullName
}
'  $*

shell脚本按行遍历文件内容

2012年9月16日

1.使用for循环

#!/bin/bash

for i in `cat arr.dat`
do
	echo $i
done

2.使用while方法1

#!/bin/bash
cat arr.dat | 
while read line
do
	echo $line
done

3.使用while方法2
将文件重定向为while的输入

#!/bin/bash

while read line
do
	echo $line
done < arr.dat

4.awk,对每行处理时,既可以使用$0

#!/bin/bash
awk '{ print $0 }' arr.dat

5.还有其他方式,比如sed等

linux下find常见指令组合

2012年9月15日

find是个很有效而且常用的命令,我们一般用到如下格式

find . -name *.txt

用来递归查找当前目录下的txt文件。再来看看其他组合。

1.根据权限查询

find . -perm 644

匹配该文件的所有者可以读写,组用户可以读,其他可以读的文件。

2.根据用户或者组来查询

find . -user root -group root

3.根据修改时间来查询
查询最近5天内修改过的文件

find . -mtime -5

查询5天前被修改过的文件

find . -mtime +5

查询修改时间比file1新但是比file2旧的文件

find . -newer file1 !file2

4.根据类型查询

find . -type f

类型可以是f,d,c,p,l,b

5.根据文件大小

-size n[cwbkMG]
              File uses n units of space.  The following suffixes can be used:

              `b'    for 512-byte blocks (this is the default if no suffix is used)

              `c'    for bytes

              `w'    for two-byte words

              `k'    for Kilobytes (units of 1024 bytes)

              `M'    for Megabytes (units of 1048576 bytes)

              `G'    for Gigabytes (units of 1073741824 bytes)

比如查找大小为62字节的文件

find . -size 62c

find后面可接的操作

print–默认都有该操作
exec—对匹配的文件执行该参数给出的shell命令,格式为

-exec ls -l {} \;

注意ls -l无需添加符号,{}中不能有空格,{}与\之间有空格,结尾还需要分号。
ok–和exec一样,不过在执行前需要经过用户的确认。

Linux下的paste命令

2012年9月14日

今天看到一个有趣的指令“paste”,用于将文本文件或者标准输出中的内容粘贴出来,可以形成新的文件。用法如下:

paste 指令 文件1 文件2

-d:设置新的域分割符,默认为空格或者tab
-s:每个文件粘贴成一行
-:从标准输入中读取数据

1.

paste file1 file2

会将file1与file2的第一行依次放在第一行,file1与file2的第二行依次放在第二行。。。
2.

paste -d:  file1 file2

file1与file2的分割符为:
3.

paste -d: -s file1 file2

file1各行按:隔开显示在第一行,file2的显示在第二行
4.

ls | paste -d" " - - - - -

可以通过-,来设置从标准输出得到的结果每行显示个数。