8. 应用软件
程序包命令位于/usr/sbin/目录中,必须有超级用户权限才可以使用pkgadd和pkgrm命令。缺省情况下,pkgadd和pkgrm命令使用/var/sadm/install/admin/default文件中信息
pkgadd用于安装程序包,命令格式为“pkgadd –d device-name [-a admin-file] pkgid”。“pkgadd –d /cdrom/cdrom0 SUNWssser”表示从/cdrom/cdrom0中安装一个名叫SUNWpdgA的软件程序包。“pkgadd -d”必须使用-d选项声明想安装的程序包在设备中的全部路径;而只使用pkgadd未跟参数会在/var/spool/pkg目录中寻找程序包。pkgadd命令更新文件/var/sadm/install/conteats(整个系统中软件包映像文件),此文件为系统中所有已安装的软件包的记录文件。
软件包可以由安装CD-ROM中拷贝过来存放在系统中,但此时并未安装此软件包。例如,一个服务器可以拷贝存贮一个软件包,多个没有CD-ROM设备的Client系统可以从服务器上安装此软件包。
spool一个软件包到/var/spool/pkg目录下
# pkgadd -d /cdrom/solaris_2.2 -s spool SUNWaudio
Transferring package instance
使用“pdgchk pkgid”检查已安装的程序包的完整性、安装路径、文件内容和文件属性。“pkgchk -p pathname”检查安装在一指定路径下的所有程序包。-a检查文件属性,-c检查文件内容。
pkginfo显示已安装程序包的信息。
pkginfo [ -d device | pathname] -1 pkg_name
例如要查找qualix HA软件的详细版本信息,则可以先执行“pkginfo | grep -i QUAL”查出qualix HA的包名是QUALha,再执行pkginfo –l QUALha就可以得到该软件信息。
删除程序包“pkgrm packageName” 。pkgrm命令根据文件/var/sadm/install/contents确定软件包地址,当软件包删除后,更新此文件。
admintool是Solaris2.x中通过图形界面使用package命令来安装和删除软件的工具。
Solaris 2.6提供了两个管理补丁程序的命令patchadd和patchrm,分别用于安装目录格式的补丁程序和删除已安装的补丁程序。如何安装和删除补丁的详细资料包含在每个补丁程序所带的install.info文件中。
rdist命令用于在远程主机之间同步部分或整个文件系统,它比较源和目标的文件状态,并只拷贝需要修改的文件。rdist是从一个中心服务器散步文件的最佳方法,它可用于当一个应用程序安装成功后,采用rdist去修订别的应用程序服务器(即共享文件系统中的“推文件”操作)。
9. SHELL编程
参见《solaris高级系统管理员指南》第16、17章
“. .profile”用于执行.profile
注意SHELL中引号 "(展开$变量) ’(不展开$变量) `(执行命令)的区别
特定变量参数
$*: B Shell或K Shell列出命令行参数的值;C Shell中不用,用$argv代替
$#: B Shell或K Shell 列出命令行参数的数目;C Shell返回变量数组中的变量个数
$?: B Shell或K Shell返回上条命令退出态(0成功);C Shell用来检测一个变量是否被设置
$$: All Shell返回当前进程号
$!: B Shell或K Shell返回在后台运行的上一个进程的进程号
$@: 与$#相同,但是使用时加引号,并在引号中返回每个参数
$-: 显示shell使用的当前选项,与set命令功能相同
B SHELL中设置环境变量如下:
MAILCHECK=600; export MAILCHECK
PATH=.:/home1/winsor:/usr/openwin:/home2/frame/bin; export PATH
C SHELL中设置环境变量如下:
setenv MAILCHECK 600
setenv path (. /home1/winsor /usr/openwin /home2/frame/bin)
B Shell和K Shell中,
“2>file”表示将标准错误重定向到文件中;
“2>&1”表示将标准错误重定向为标准输出;
“<>file”表示将一个文件既做标准输入也作为标准输出;
“<&-”和“>&-”分别表示关闭标准输入和标准输出,“2>&-”表示关闭标准错误。
高级重定向: (date ‘+%B %d’; ls -l *.foo) > ls.log 2>&1
% cat ls.log
May 10
ls : *.foo: No such file or directory
date命令将其输出送往STDOUT,而ls命令(由于任何文件都没有带扩展名foo)产生错误信息,被送往STDERR。当显示ls.log文件时,你会看到STDOUT和STDERR被合并了。也可以按相反方向合并输出流,让STDOUT并入STDERR中,当这样不符合习惯。可以使用类似m >& n的表示形式合并任意两个输出流,送往m文件描述字的输出与送往n文件描述字的输出合并在一起。
分析shell脚本首行代码的意义。
Bourne #!/bin/sh
Korn #!/bin/ksh
C #!/bin/csh-f
用-f(快速的)选项使用/bin, /csh运行脚本但不引用.cshrc文件。
SHELL输入输出的重点
command > filename 2>&1 把把标准输出和标准错误一起重定向到一个文件中
command >> filename 2>&1 把把标准输出和标准错误一起重定向到一个文件中(追加)
command < filename >filename2 把command命令以filename文件作为标准输入,以filename 2文件作为标准输出
B SHELL语法
IF语句
grep用于查看Dave是否在数据文件data.file中,注意‘Dave\>’用于精确匹配
if grep ’Dave\>’ data.file > /dev/null 2>&1
then
echo "Great Dave is in the file"
else
echo "No Dave is not in the file"
fi
用if语句测试文件权限
LOGFILE=test.txt
if [! -w "$LOGFILE"]; then
echo " You cannot write to $LOGFILE " > &2
fi
if语句可用来测试传入脚本中参数的个数。使用特定变量$#,表示调用参数的个数。
if [ $# -lt 3 ]; then
echo "Usage: `basename $0` arg1 arg2 arg3" > &2
exit 1
fi
嵌套IF
DIR_NAME=testdirec
THERE=`pwd`
mkdir $DIR_NAME > /dev/null 2>&1
if [ -d $DIR_NAME ]; then
cd $DIR_NAME
if [ $? = 0 ]; then
HERE=`pwd`
cp $THERE/*.txt $HERE
else
echo "Cannot cd to $DIR_NAME" >&2
exit 1
fi
else
echo "Cannot create directory $DIR_NAME" >& 2
exit 2
fi
多文件位置检测,演示elif用法
LOCAT_1=/usr/opts/audit/logs/audit.log
LOCAT_2=/usr/local/audit/audit.logs
if [ -r $LOCAT_1 ]; then
echo "Using LOCAT_1"
cat $LOCAT_1
elif
[ -r $LOCAT_2 ]
then
echo "Using LOCAT_2"
cat $LOCAT_2
else
echo "`basename $0`: sorry the audit file is not readable or cannot be located." >&2
exit 1
fi
CASE语句
echo -n "enter a number from 1 to 5:"
read ANS
case $ANS in
1) echo "you select 1"
;;
2) echo "you select 2"
;;
*) echo "`basename $0`: This is not between 1 and 5" >&2
exit 1
;;
esac
echo -n "Do you wish to proceed [y..n] :"
read ANS
case $ANS in
y|Y|yes|Yes) echo "yes is selected"
;;
n|N) echo "no is selected"
exit 0
;;
*) echo "`basename $0` : Unknown response" >&2
exit 1
;;
esac
FOR语句
打印字符串列表
for loop in "orange red blue grey"
do
echo $loop
done
for loop in `ls LPSO*`
do
echo $loop
cat $files | tr "[a-z]" "[A-Z]" >$files.UC
done
UNTIL语句
until循环做监视条件也很有用。假定要监视文件系统容量,当它达到一定水平时通知超级用户。
LOOK_OUT=`df | grep /logs | awk ’{print $5}’ | sed ’s/%//g’`
echo $LOOK_OUT
until [ $LOOK_OUT" -gt "90" ]
do
echo "FileSystem..logs is nearly full" | mail root
exit 0
done
WHILE语句
使用while循环读键盘输入
count=0
echo -n "enter your most liked film :"
while read FILM
do
echo "Yeah, great film the $FILM"
count=`expr $count+1`
done
用while循环从文件中读取数据
while read LINE
do
echo $LINE
done < names.txt
使用IFS读文件
文件names.txt中内容如下:
Louise Conrad:Accounts:ACC8987
Peter James:Payroll:PR489
Fred Terms:Customer:CUS012
SAVEDIFS=$IFS
IFS=:
while read NAME DEPT ID
do
echo -e "$NAME\t $DEPT\t $ID"
done < name.txt
IFS=$SAVEDIFS
输出结果如下:
Louise Conrad Accounts ACC8987
Peter James Payroll PR489
Fred Terms Customer CUS012
死循环,跳出需要break
while:
do
命令
done
函数定义和调用
测试目录存在
is_it_a_directory()
{
### 参数数量小于1
if [ $# -lt 1 ]; then
echo "is_it_a_directory: I need an argument"
return 1
fi
### 判断是否是目录
_DIRECTORY_NAME=$1
if [ ! -d $_DIRECTORY_NAME ]; then
return 1
else
return 0
fi
}
echo -n "enter destination directory :"
read DIREC
if is_it_a_directory $direct;
then
else
echo "$DIREC does not exist, create it now? [y..n]"
fi
命令行参数控制
SHIFT命令
向脚本传递参数时,有时需要将每一个参数偏移以处理选项,这就是shift命令的功能。它每次将参数位置向左偏移一位。例如下面这个程序使用shift命令来处理传递到脚本的每一个参数,这样只需要打印$1变量就可以显示所有参数
while [ $# -ne 0 ]
do
echo $1
shift
done
GETOPTS命令
有时有必要在脚本中指定命令行选项取值。getopts为此提供了一种方式,即在option_string中将一个冒号放在选项后。例如:
getopt sahfvc: OPTION
上面一行脚本指出,选项a、h、f可以不加实际值进行传递,而选项c必须取值。使用选项取值时,必须使用变量OPTARG保存该值。如果试图不取值传递此选项,会返回一个错误信息。错误信息提示并不明确,因此可以用自己的反馈信息屏蔽它,方法如下:将冒号放在option_string开始部分。
while getopts :ahfc: OPTION
while getopts :ahfc: OPTION
do
case $OPTION in
a) ALL=true
echo "ALL is $ALL"
;;
h) HELP=true
echo "HELP is $HELP"
;;
f) FILE=true
echo "FILE is $FILE"
;;
c) COPIES=$OPTARG
echo "COPIES is $COPIES"
\?) # usage statement
echo "`basename $0` -[a h f v] -[c value] file" >&2
;;
esac
done
命令行:getopt1 -ah –c 3
SHELL编写的自动FTP脚本,详见632 Linux 与Unix Shell 编程指南 第25和27章
ftp -i -n $DEST_HOST << FTPIT
user anonymous $USER@$THISHOST
$MODE
get $FILENAME $DIREC/$FILENAME.ftp
quit
FTPIT
在SHELL中输出显示用echo,输入用read,子命令执行采用exec
#!/bin/sh
echo "First Name:\c"
read name
echo "Last Name:\c"
read surname
采用trap在脚本中捕捉信号
trap可以使你在脚本中捕捉信号。该命令的一般形式为:
trap name signal(s)
其中,name是捕捉到信号以后所采取的一系列操作。实际生活中,name一般是一个专门用来处理所捕捉信号的函数。Name需要用双引号(“”)引起来。Signal就是待捕捉的信号。
脚本在捕捉到一个信号以后,通常会采取某些行动。最常见的行动包括:
1)清除临时文件
2)忽略该信号
3)询问用户是否终止该脚本的运行
下表列出了一些最常见的trap命令用法:
trap "" 2 3 忽略信号2和信号3,用户不能终止该脚本
trap "commands" 2 3 如果捕捉到信号2或3,就执行相应的commands命令
trap 2 3 复位信号2和3,用户可以终止该脚本
也可以使用单引号(‘’)来代替双引号(“”);其结果是一样的。
C Shell中,“>file”、“>>file”和“& file”将标准错误和标准输出重定向到文件,“>>& file”将标准错误和标准输出追加到文件。
C shell中的$argv
$#argv 返回命令行参数的数目
$* 返回所有参数的值
$argv 返回所有参数的值
$argv[1-3] 返回参数1-3的值
$0 返回运行这个脚本的命令名
$argv[n] 返回第n个参数
$argv[$#argv] 返回最后一个参数
注意$argv[0]没有含义,它并不能像$0一样返回脚本的名称
C shell中的变量修改符
:e 删除前缀(以“点“结尾的部分)
:h 删除末尾的文件名部分
:r 删除后缀(以“点“开始的部分)
:t 删除目录部分
:q 强制变量进行引用(用来引用$argv)
:x 和q选项一样,只是在碰到空格,制表符或新行时产生一个词
C SHELL语法
IF语句
if ($#argv == 0) then
echo "zero"
else if ($#argv > 0) then
echo "more than zero"
else
echo "less than zero"
endif
SWITCH语句
echo "Terminal type? \c"
set term = $<
switch ($term)
case tvi950:
case vt100:
case sun:
setenv TERM $term
breaksw
default:
echo "I don’t know that one."
breaksw
endsw
FOREACH语句
foreach file (*.c)
echo $file
cc -o $file:r $file
end
WHILE语句
while($#argv != 0)
echo "argument: $1"
shift
end
计算语句
C shell中的@命令和Bourne和Kornshell中的expr命令有相同的作用
@total=5+3
@total++
@total+=4
使用调试标志
所有的三种shell提供-x(echo)和-v(verbose)选项,使用它们可以帮助找出问题在脚本中出现的地方。-v 选项显示当从文件读取脚本时显示脚本的每一行。-x 选项显示被shell处理过之后并等待执行时各行的内容。组合这两个选项可以为调试脚本提供更多有用的信息。
10. 其它(不常用命令)
在ATT系统中,系统管理员可以指定谁可以或不可以使用cron。这是使用称为cron.allow和cron.deny的两个配置文件来完成的。在solaris中,crontab文件位于/var/spool/cron/crontabs目录中,诸如cron.allow和cron.deny等配置文件在/etc/cron.d目录中,要打开cron的登记功能,应编辑/etc/default/cron并设置CRONLOG=YES,这将导致登记信息被写到/var/cron/log文件中。Crontab中配置的程序一旦运行错误,crontab自动会给Adm发mail通知,Adm可以通过mail命令来察看是哪一条命令有误。
提交crontab文件采用crontab cronfile,删除crontab文件用crontab –r
HP_UX:cron进程执行命令时写日志/var/adm/cron/log
at命令允许用户向cron守护进程提交作业,使其在稍后的时间运行。一旦一个作业被提交, at命令将会保留所有当前的环境变量,包括路径,不象crontab,只提供缺省的环境。和crontab一样,根用户可以通过/etc目录下的at.allow和at.deny文件来控制哪些用户可以使用at命令,哪些用户不行。不过一般来说,对at命令的使用不如对crontab的使用限制那么严格。
at命令的基本形式为:
at [-f script] [-m -l -r] [time] [date]
其中,
-f script 是所要提交的脚本或命令。
-l 列出当前所有等待运行的作业。atq命令具有相同的作用。
-r 清除作业。为了清除某个作业,还要提供相应的作业标识( ID);有些UNIX变体只接受at rm作为清除命令。
-m 作业完成后给用户发邮件。
time at命令的时间格式非常灵活;可以是HHH.HHMM、HH:MM或H:M,其中H和M分别是小时和分钟。还可以使用a.m.或p.m.。
date 日期格式可以是月份数或日期数,而且at命令还能够识别诸如today、tomorrow这样的词。
如果你正在运行一个进程,而且你觉得在退出帐户时该进程还不会结束,那么可以使用nohup命令。该命令可以在你退出帐户之后继续运行相应的进程。nohup就是不挂起的意思(no hang up)。该命令的一般形式为:nohup command &
nm 显示系统内部参数名表。
/usr/ccs/bin/nm cmd
程序编译完成生成一个参数的符号表。Nm就是用来查看二进制程序的符号表.
/dev/ksyms 是一个程序来读核心的符号表的驱动。
#/usr/ccs/bin/nm /dev/ksyms
查看整个核心的符号表(变量表,也是内核参数表)是用file cmd 能看出是否该程序有符号表。例如:#file cp 如果最后有stripped 说明符号表被去掉了,如果没有说明该执行程序有符号表。
ndd 用来查看和修改os与网络有关的参数
#ndd /dev/ip \? 查看所有ip的参数
#ndd /dev/tcl \? 查看所有tcp模块的参数
#ndd /dev/ip ip_forwarding 查看ip模块的某个参数
#ndd /dev/udp udp_recv_hiwat
#ndd -set /dev/ip ip_forwarding 1 修改ip模块的某个参数。
修改内核参数在/etc/system文件。
# /etc/system
set [modulename:]variablename = value
#reboot 系统
HP_UX中参数文件为/stand/system
分析系统core文件。
#iscda unixcore dumpfile > a.txt
iscda, 用于分析/var/crash目录下的core文件,或有符号表的core文件,不是系统命令.
#file core 查看core 文件由什么文件生成。例如是由/bin/vi 生成
#adb /bin/vi core 2 > &1 | tee /tmp/mycore
安装完Linux后,要使该机的telnet、ftp等服务启动,必须将/etc/inetd.conf中telnet和ftp服务的注释放开。并修改hosts.allow和hosts.deny如下:
1) 在hosts.allow中增加 "ALL : ALL"
2) 将hosts.deny中"ALL : ALL"注释掉
在netscape和Apache中,httpd的配置文件和参数不太一样。
用rdate同步多台主机时钟。
Linux和Solaris不同,使用ps看到的还包括子进程,例如
root 657 1 0 01:33 ? 00:00:00 /opt/aimc/0/pmail/pmail -o -m 8
aimc 660 657 0 01:33 ? 00:00:00 /opt/aimc/0/pmail/pmail -o -m 8
aimc 661 660 0 01:33 ? 00:00:00 /opt/aimc/0/pmail/pmail -o -m 8
aimc 663 660 0 01:33 ? 00:00:01 /opt/aimc/0/pmail/pmail -o -m 8
aimc 839 660 0 01:33 ? 00:00:04 /opt/aimc/0/pmail/pmail -o -m 8
实际只有657是真正的pmail服务。
Solaris在/etc/skel目录下提供每个shell默认的用户初始文件local.*
当/etc/shells中未设置当前正使用的SHELL类型时,ftpd被禁止。
如果执行命令时忘记键入&,可以键入ctrl+z来挂起服务,然后键入bg将其切入后台。
目前系统中记帐文件通常位于/var/adm目录下。记帐记录是每个进程结束时写的,永不终止的进程不产生记帐信息。
命令 rpcinfo用来提供有关RPC服务的信息。
例如: 显示程序号,版本,协议,端口,服务和RPC服务的自身。
# rpcinfo
标识所有在主机上注册的RPC服务
# rpcinfo –p [hostname]
program ver proto port service
100000 4 tcp 111 portmapper
100007 1 udp 32771 ypbind
100008 1 udp 32803 walld
100012 1 udp 32805 sprayd
DNS名字服务器是一个实际上的守护进程,作为DNS服务器运行在主机的配置中。在SunOS操作系统中执行BIND的守护进程的名字是: /usr/sbin/in.named
DNS中MX记录格式如下:
Name [ttl][class] MX performance host…
例如:
piper IN MX 10 piper
IN MX 20 mailhub
IN MX 50 boulder.colorado.edu.
xterm1 IN MX 10 mailhub
IN MX 20 anchor
IN MX 50 boulder.colorado.edu
优先级最小的主机首先尝试,因此0代表最高优先级,65535代表最低优先级,例如收信人为bob@xterm1的邮件一旦mailhub可访问就发给它,否则anchor是第二选择,当mailhub和anchor都不工作时就发给boulder。注意boulder使用全名,因为它不是缺省域。
DNS数据库可以支持通配的MX记录:
* IN MX 10 mailhub.cs.colorado.edu.
11. 正则表达式
基本元字符集及其含义
^ 只匹配行首
$ 只匹配行尾
* 一个单字符后紧跟*,匹配0个或多个此单字符
[ ] 匹配[ ]内字符。可以是一个单字符,也可以是字符序列。可以使用-表示[ ]内字符序列范围,如用[1-5]代替[12345]
\ 用来屏蔽一个元字符的特殊含义。因为有时在shell中一些元字符有特殊含义。\可以使其失去应有意义
. 匹配任意单字符
pattern\{n\} 用来匹配前面pattern出现次数。n为次数
pattern\{n, \}m 含义同上,但次数最少为n
pattern\{n, m\} 含义同上,但pattern出现次数在n与m之间
[Cc]omputer匹配Computer或computer两个单词
注意^符号的使用,当直接用在第一个括号里,意指否定或不匹配括号里内容。[^a-zA-Z]匹配任一非字母型字符,而[^0-9]匹配任一非数字型字符
“A\{2\}B”匹配字母A出现两次,并以B结尾;
“A\{4,\}B”匹配A至少4次,并以B结尾;
“A\{2,4\}B”出现2次到4次之间,并以B结尾;
12. 常用命令
finger 后跟任意一个数字,会给出当前机器所有用户信息。finger @10.1.1.4 finger后加@加任意IP和机器名,都会得到指定机器的的用户信息
finger命令显示登录到系统的用户的登录名列表,可以采用who、finger、rusers -l或whodo中的任何一个查找当前登录系统的用户。其中who命令还可以显示登录用户所在client段IP
who命令选项
-a: 显示所有的结果。
-r: 显示当前的运行级别(在LINUX系统中应当使用runlevel命令)。
-s: 列出用户名及时间域。
whoami显示执行该命令的用户名。这不是who命令的一个选项,可以单独应用。
who命令可以显示当前有哪些用户登录到系统上。要显示当前登录的用户,可以用who,要显示自己的用户名,可以用whoami
通知用户,write username和wall命令
文件对比时的常用命令
sort -k 2,2 -t \| -o obs_163.out.sort obs_163.in
根据文件obs_163.ini中第2到2个字段为索引排序,各字段间以‘|’分隔
sort -u -c obs_163.out.sort (-u 判重 -c 只做检查不做修改)
comm -13 file1 file2 > file2.only (将只存在于file1中和file1、file2共有的内容删除,实际上就是保留只存在于file2中的内容)
cat file1 file2 | sort | uniq 将file1和file2中所有重复行只挑选出一行
“ipcs -m”用于显示系统中共享内存分配情况,例如结果如下:
IPC status from as of Wed Oct 17 14:50:26 CST 2001
T ID KEY MODE OWNER GROUP Shared Memory:
m 3506 0xc8 --rw-r----- paid aisoft
m 307 0x12c --rw-r----- aimc aisoft
如果要清除某块Shared Memory可以使用命令“ipcrm -m”, 例如“ipcrm -m 3506”
priocntl命令显示或者设置指定进程的调度参数(-l 或者-ecl等选项)
nice修改一个命令或进程的优先权,例如nice -10 command_name, 减表示提高优先权,加表示降低优先权。谦让值越小,优先级越高。
date命令格式
date option +%format
date +%d%m%y 090699
date +%d-%m-%y 09-06-99
date +%A%e" "%B" "%Y Wednesday 9 June 1999
date +%A" "%R" "%P Wednesday 10:09 AM
date +%A" "%T Wednesday 10:31:19
复杂的find命令,命令格式
find pathname -options [-print -exec -ok]
选项列表如下:
-name 按照文件名查找文件。
-perm 按照文件权限来查找文件。
-prune 使用这一选项可以使find命令不在当前指定的目录中查找,如果同时使用了-depth选项,那么-prune选项将被find命令忽略。
-user 按照文件属主来查找文件。
-group 按照文件所属的组来查找文件。
-mtime -n +n 按照文件的更改时间来查找文件, - n表示文件更改时间距现在n天以内,+ n表示文件更改时间距现在n天以前。Find命令还有-atime和-ctime选项,但它们都和-mtime选项相似,所以我们在这里只介绍-mtime选项。
-nogroup 查找无有效所属组的文件,即该文件所属的组在/etc/groups中不存在。
-nouser 查找无有效属主的文件,即该文件的属主在/etc/passwd中不存在。
-newer file1 ! file2 查找更改时间比文件file1新但比文件file2旧的文件。
-type 查找某一类型的文件,诸如:
b - 块设备文件。
d - 目录。
c - 字符设备文件。
p - 管道文件。
l - 符号链接文件。
f - 普通文件。
-size n[c] 查找文件长度为n块的文件,带有c时表示文件长度以字节计。
-depth 在查找文件时,首先查找当前目录中的文件,然后再在其子目录中查找。
-fstype 查找位于某一类型文件系统中的文件,这些文件系统类型通常可以在配置文件/etc/fstab中找到,该配置文件中包含了本系统中有关文件系统的信息。
-mount 在查找文件时不跨越文件系统mount点。
-follow 如果find命令遇到符号链接文件,就跟踪至链接所指向的文件。
-cpio 对匹配的文件使用cpio命令,将这些文件备份到磁带设备中。
在当前目录下查找大于200K的文件采用“find . –size +200 -exec ls -l {} \;”
如果希望在/apps目录下查找文件,但不希望在/apps/bin目录下查找,可以用:
$ find /apps -name "/apps/bin" -prune -o -print
“find . -name "aimc*.ini" -print | xargs grep $1”,在当前所有子目录下查找包含指定字符$1的aimc*.ini文件
“find / -xdev –name core –atime +7 –exec rm –f {} ’;’ ”删除一周内没有访问过的core文件,其中-xdev参数保证find不会跨越到除根以外的其他文件系统上。
“find /var/preserve -mtime +14 -exec rm –f {} ‘;’”把/var/preserve目录下两周前最后修改过的文件删掉。
“find / -user root -perm –4000 -print”用来查找具有setuid许可权的文件。
“cd /tmp; find . ! –name . ! –name lost+found –type d –mtime +3 –exec /bin/rm –rf {} ‘;’”递归删除/tmp目录下72 小时内没有改动过的任何子目录。
“find . –name two.txt –or -print”显示除了指定的two.txt之外的所有文件,-or选项用于除了符合条件之外的。
如果要把当前目录下(包括子目录)符合某条件的所有文件都检索出来并转移到指定目录下,可以采用以下几种方式:
1. find . –name “IP*_200305??.????” -exec mv {} /tmp \;
语句中“{}”表示find语句查询结果,“\;”或者“’;’”表示复合语句结束标志。因为“;”在SHELL命令行中不能直接写,所以或者用“\”转义,或者用引号括起来。
2. 另外可以通过awk来实现,“find . -name "txt?" | awk ’{ system(sprintf("mv %s /tmp \n", $0))}’”
3. 用SHELL方式实现,
#!/bin/sh
for i in `find ./ -name "test*" -print | cat`
do
mv $i ./prog
done
find命令和xargs命令的配合
在使用find命令的-exec选项处理匹配到的文件时,find命令将所有匹配到的文件一起传递给exec执行。不幸的是,有些系统对能够传递给exec的命令长度有限制,这样在find命令运行几分钟之后,就会出现溢出错误。错误信息通常是“参数列太长”或“参数列溢出”。这就是xargs命令的用处所在,特别是与find命令一起使用。find命令把匹配到的文件传递给xargs命令,而xargs命令每次只获取一部分文件而不是全部,不像-exec选项那样。这样它可以先处理最先获取的一部分文件,然后是下一批,并如此继续下去。在有些系统中,使用-exec选项会为处理每一个匹配到的文件而发起一个相应的进程,并非将匹配到的文件全部作为参数一次执行;这样在有些情况下就会出现进程过多,系统性能下降的问题,因而效率不高;而使用xargs命令则只有一个进程。另外,在使用xargs命令时,究竟是一次获取所有的参数,还是分批取得参数,以及每一次获取参数的数目都会根据该命令的选项及系统内核中相应的可调参数来确定。
在/apps/audit目录下查找所有用户具有读、写和执行权限的文件,并收回相应的写权限:
$ find /apps/audit -perm -7 -print | xargs chmod o-w
“man –k keyword”命令输出在它们的单行梗概中出现keyword的手册页面的清单;“man –P PAGER”指定哪一个分页程序应该被用来显示手册页,默认为less命令
“tail –f filename”显示一个文件末尾,然后等待更多的输入,常用于看Log文件;“tail –n NUM”显示指定文件最后NUM行;-v显示文件名标题行
truss命令用于跟踪系统调用和signal,-p选项用于指定进程号。
sa命令,或者按用户(/var/adm/usracct)或者按命令(/var/adm/savacct)汇总CPU数据。
由login写在wtmp文件中的连接时间记录是跟踪误用的最有用的记帐信息,ac命令按个人(-p)或按日期(-d)汇总wtmp文件中的数据。记帐功能,详见solaris.doc
在HP_UX中: /var/adm/wtmp包含成功login的历史记录,采用last命令显示;/var/adm/btmp包含不成功login记录,采用lastb命令显示;/var/adm/utmp包含所有logged onto the system的记录。这三个文件都不是ASCII文件,
diff命令,-b或-w选项可忽略对空格、Tab和回车符的修改;-i选项忽略从大小写间的差异;-q选项仅报告文件是否不同,不问细节;-r选项递归比较所有子目录;-s选项当两个文件相等时发出报告
dircmp类似diff命令,比较目录
basename和dirname
basename从路径中分离出文件名,格式:basename path
dirname从全路径文件名中分离出路径名,格式:dirname pathname
fuser用法
-k:杀死所有访问该文件或文件系统的进程。
-u:显示访问该文件或文件系统的所有进程。
fuser命令可以显示访问某个文件或文件系统的所有进程。在有些系统上-u和-m选项可以互换。还可以在if语句中使用fuser命令。要列出设备/dev/hda5上的所有活动进程,使用: fuser -m /dev/hda5
要杀死设备/dev/hda5上的所有进程,使用:fuser –k /dev/hda5
fuser -ku /home/cb 相当于将访问/home/cb的所有用户显示并杀掉
nl命令可用于在文件中列行号,在打印源代码或列日志文件时很有用
nl options file
-I:行号每次增加n;缺省为1
-p:在新的一页不重新计数
grep命令,-i选项忽略在模式参数和输入文件中的大小写区别,-n选项在输出的每行之前加上行号,-w选项仅显示匹配文件组成整词的行,-x选项仅显示匹配文件恰在一整行的行,-v选项反转查找仅显示没有匹配的行,-h 查询多文件时不显示文件名,-l 查询多文件时只输出包含匹配字符的文件名
grep 命令支持正则表达式,例如:
grep ’[A-Z][A-Z]...C’ data.f 查询头两个是大写字母,中间两个任意,并以C结尾;
grep ’^[^48]’ data.f 查询其行首不是48,可以在方括号中使用^记号,表明查询在行首开始。
“kill -9”中的-9即信号ID为9的SIGKILL,实际kill命令本身只负责发送信号并不杀进程。而kill –SIGKILL发送杀进程信号,kill –SIGHUP即kill –1挂起进程。“kill –l”用于显示kill可操作的信号列表 kill –HUP –16 –17查一下
strings显示一个binary文件中的可打印字符,它会在binary文件中寻找可打印字符序列
在.cshrc中设置“stty erase ^H”,表示删除时用Backspace键,否则只能用Del键。
stty的一个可用选项为:stty-g。
此选项允许以可读格式保存stty现有设置,便于以后重置回stty。正像前面在文件/etc/profile中看到的一样。将stty-g内容放入一个变量中,工作完成后,任何改动的设置将被写回stty。
SAVEDSTTY=`stty -g`
stty -echo
... ...
stty $SAVEDSTTY
whereis命令能够给出系统命令的二进制文件及其在线手册的路径,类似which,但多一个man文件路径。采用-b选项,将只罗列出二进制文件的路径。
13. awk介绍
(详见632 Linux 与Unix Shell 编程指南 第9章)
有三种方式调用awk,第一种是命令行方式,如:
awk [-F field-separator] ’commands’ input-file(s)
这里,commands是真正的awk命令。本章将经常使用这种方法。上面例子中,[-F域分隔符]是可选的,因为awk使用空格作为缺省的域分隔符,因此如果要浏览域间有空格的文本,不必指定这个选项,但如果要浏览诸如passwd文件,此文件各域以冒号作为分隔符,则必须指明-F选项,如:
awk -F: ’commands’ input-file
第二种方法是将所有awk命令插入一个文件,并使awk程序可执行,然后用awk命令解释器作为脚本的首行,以便通过键入脚本名称来调用它。
第三种方式是将所有的awk命令插入一个单独文件,然后调用:
awk -f awk-script-file input-file(s)
-f选项指明在文件awk_script_file中的awk脚本,input_file(s)是使用awk进行浏览的文件名。
任何awk语句都由模式和动作组成。在一个awk脚本中可能有许多语句。模式部分决定动作语句何时触发及触发事件。处理即对数据进行的操作。如果省略模式部分,动作将时刻保持执行状态。
模式可以是任何条件语句或复合语句或正则表达式。模式包括两个特殊字段BEGIN和END。使用BEGIN语句设置计数和打印头。BEGIN语句使用在任何文本浏览动作之前,之后文本浏览动作依据输入文件开始执行。END语句用来在awk完成文本浏览动作后打印输出文本总数和结尾状态标志。如果不特别指明模式,awk总是匹配或打印行数。
实际动作在大括号{}内指明。动作大多数用来打印,但是还有些更长的代码诸如if和循环(looping)语句及循环退出结构。如果不指明采取动作,awk将打印出所有浏览出来的记录。
awk执行时,其浏览域标记为$1,$2...$n。这种方法称为域标识。使用这些域标识将更容易对域进行进一步处理。使用$1,$3表示参照第1和第3域,注意这里用逗号做域分隔。如果希望打印一个有5个域的记录的所有域,不必指明$1,$2,$3,$4,$5,可使用$0,意即所有域。因为域间使用空格作为域分隔符,故不必用-F选项划分域。
例如:打印grade.txt中第1和4列
awk ‘{print $1,$4}’ grade.txt
条件操作
1. 匹配
为使一域号匹配正则表达式,使用符号‘~’后紧跟正则表达式,也可以用if语句。awk中if后面的条件用()括起来。这样可以写出表达式{if($4~/brown/) print}意即如果field-4包含brown,打印它。如果条件满足,则打印匹配记录行。可以编写下面脚本,因为这是一个动作,必须用花括号{}括起来。
awk ’$0 ~ /Brown/’ grade.txt
2. 精确匹配
为精确匹配48,使用等号==,并用单引号括起条件。例如$3==“48”,这样确保只有48序号得以匹配,其余则不行。
awk ’$3=="48" {print $0}’ grade.txt
3. 不匹配
有时要浏览信息并抽取不匹配操作的记录,与~相反的符号是!~,意即不匹配。像原来使用查询brown腰带级别的匹配操作一样,现在看看不匹配情况。表达式$0 !~ /brown/,意即查询不包含模式brown腰带级别的记录并打印它。
awk ’{if($4 !~ /Brown/) print $0}’ grade.txt
如果想要查询非brown-2的腰带级别,可做如下操作:
awk ’$4 != "Brown-2" {print $0}’ grade.txt
4. 列比较
查询第6列值大于第7列的行
awk ’{if ($6 > $7) print $0}’ grade.txt
5. 大小写
awk ’/[Gg]reen/’ grade.txt
6. 任意字符
抽取名字,其记录第一域的第四个字符是a,使用句点.。表达式/^...a/意为行首前三个字符任意,第四个是a,尖角符号代表行首。
awk ’$1 ~/^...a/’ grade.txt
7. 或关系匹配
为抽取级别为yellow或brown的记录,使用竖线符|。意为匹配|两边模式之一。注意,使用竖线符时,语句必须用圆括号括起来。
awk ’$0~/(Yellow|Brown)/’ grade.txt
8. 行首
不必总是使用域号。如果查询文本文件行首包含48的代码,可简单使用下面^符号:
awk ’/^48/’ input-file
9. 条件与或
awk ’{if ($1=="P.Bunny" && $4=="Yellow") print $0}’ grade.txt
awk ’{if ($4=="Yellow" || $4~/Brown/) print $0}’ grade.txt
当第一次使用awk时,可能被错误信息搅得不知所措,但通过长时间和不断的学习,可总结出以下规则。在碰到awk错误时,可相应查找:
1.确保整个awk命令用单引号括起来。
2.确保命令内所有引号成对出现。
3.确保用花括号括起动作语句,用圆括号括起条件语句。
4.可能忘记使用花括号,也许你认为没有必要,但awk不这样认为,将按之解释语法。
awk内置变量
ARGC 命令行参数个数
ARGV 命令行参数排列
ENVIRON 支持队列中系统环境变量的使用
FILENAME awk浏览的文件名
FNR 浏览文件的记录数
FS 设置输入域分隔符,等价于命令行-F选项
NF 浏览记录的域个数
NR 已读的记录数
OFS 输出域分隔符
ORS 输出记录分隔符
RS 控制记录分隔符
ARGC支持命令行中传入awk脚本的参数个数。ARGV是ARGC的参数排列数组,其中每一元素表示为ARGV[n],n为期望访问的命令行参数。
ENVIRON支持系统设置的环境变量,要访问单独变量,使用实际变量名,例如ENVIRON[“EDITOR”]=“Vi”。
FILENAME支持awk脚本实际操作的输入文件。因为awk可以同时处理许多文件,因此如果访问了这个变量,将告之系统目前正在浏览的实际文件。
FNR支持awk目前操作的记录数。其变量值小于等于NR。如果脚本正在访问许多文件,每一新输入文件都将重新设置此变量。
FS用来在awk中设置域分隔符,与命令行中-F选项功能相同。缺省情况下为空格。如果用逗号来作域分隔符,设置FS=","。
NF支持记录域个数,在记录被读之后再设置。
OFS允许指定输出域分隔符,缺省为空格。如果想设置为#,写入OFS="#"。
ORS为输出记录分隔符,缺省为新行(\n)。
RS是记录分隔符,缺省为新行(\n)。
内置变量举例
所有学生记录被打印,并带有其记录号。使用NF变量显示每一条读记录中有多少个域,并在END部分打印输入文件名。
awk ’{print NF,NR,$0} END {print FILENAME}’ grade.txt
在从文件中抽取信息时,最好首先检查文件中是否有记录。下面的例子只有在文件中至少有一个记录时才查询Brown级别记录。使用AND复合语句实现这一功能。意即至少存在一个记录后,查询字符串Brown,最后打印结果。
awk ’{if (NR >0 && $4~/Brown/) print $0}’ grade.txt
awk操作符
1. 在文件grade.txt中创建新域diff保存域目前级别分与域最高级别分的减法值。表达式为‘{diff=$7-$6}’,语法首先测试域目前级别分小于域最高级别分。新域因此只打印其值大于零的学生名称及其新域值。在BEGIN部分加入tab键以对齐报告头。
awk ’BEGIN {print "Name\t Differecnce"} {if($6<$7) {diff=$7-$6; print $1,diff}}’ grade.txt
2. 将所有学生的‘目前级别分’加在一起,方法是tot+=$6,tot即为awk浏览的整个文件的域6结果总和。所有记录读完后,在END部分加入一些提示信息及域6总和。不必在awk中显示说明打印所有记录,每一个操作匹配时,这是缺省动作。
awk ’(tot += $6); END{ print "Club student total points :" tot} ’
如果文件很大,你只想打印结果部分而不是所有记录,在语句的外面加上圆括号()即可。
awk ’((tot+=$6)); END {print "Club student total points :" tot}’
3. 文件长度相加
在目录中查看文件时,如果想快速查看所有文件的长度及其总和,但要排除子目录,使用ls -l命令,然后管道输出到awk,awk首先剔除首字符为d(使用正则表达式)的记录,然后将文件长度列相加,并输出每一文件长度及在E N D部分输出所有文件的长度。本例中,首先用ls -l命令查看一下文件属性。注意第二个文件属性首字符为d,说明它是一个目录,文件长度是第5列,文件名是第9列。如果系统不是这样排列文件名及其长度,应适时加以改变
ls -l | awk ’ /^[^d]/ {print $9"\t"$5} {tot+=$5} END {print "total KB:" tot}’
内置字符串函数
gsub(r,s) 在整个$0中用s替代r
gsub(r,s,t) 在整个t中用s替代r
index(s,t) 返回s中字符串t的第一位置
length(s) 返回s长度
match(s,r) 测试s是否包含匹配r的字符串
split(s,a,fs) 在fs上将s分成序列a
sprint(fmt,exp) 返回经fmt格式化后的exp
sub(r,s) 用$0中最左边最长的子串代替s
substr(s,p) 返回字符串s中从p开始的后缀部分
substr(s,p,n) 返回字符串s中从p开始长度为n的后缀部分
要在整个记录中替换一个字符串为另一个,使用正则表达式格式,/目标模式/,替换模式/。例如改变学生序号4842到4899:
awk ’gsub(/4842/,4899) {print $0}’ grade.txt
查询字符串s中t出现的第一位置。必须用双引号将字符串括起来。例如返回目标字符串Bunny中ny出现的第一位置,即字符个数。
awk ’BEGIN {print index{"Bunny", "ny"}}’ grade.txt
从shell中向awk传入字符串
awk脚本大多只有一行,其中很少是字符串表示的。本书大多要求在一行内完成awk脚本,这一点通过将变量传入awk命令行会变得很容易。现就其基本原理讲述一些例子。
设置文件名为一变量,管道输出到awk,返回不带扩展名的文件名
STR="mydoc.txt"
echo $STR | awk ’{print substr($STR,1,5)}’
设置文件名为一变量,管道输出到awk,只返回其扩展名
echo $STR | awk ’{print substr($STR,7)}’
svrmgrl command=exit | awk ’/Oracle8i (Release|Version)/ {substr($3,1,3) ;print substr($3,1,3)}
awk输出函数printf,格式完全等同与同名C函数
显示ASCII码中65的等价值 awk ’BEGIN {printf "%c\n", 65}’
常用命令举例
1. ps -ef | grep psagent | grep -v grep | awk ‘{print $2}’ | xargs kill -9
批量杀掉psagent进程
2. awk -F\, ’{print $1"|"$2}’ all_data1.txt (取前两列,以‘|’分割)
3. 通过system函数调用sprintf拼接的命令
find . -name "txt?" | awk ’{ system(sprintf("mv %s /tmp \n", $0))}’
4. 复合调用awk
文件内容如下行所示:
[2002-07-21 07:37:46] User(xuefeiaa),Svc_id(8010001): 更换成功。(new_id=1690556, old_id=1659737)
从上述行中取new_id和old_id两列值
awk -F\( ’{print $4}’ change_code.txt | awk -F\) ’{print $1}’ | awk -F= ’{print $2","$3}’ | awk -F\, ’{print $1,$3}’ > ! tmp.txt
5. 从指定文件中挑出长度不是标准172字节的那些行
awk ’{if (length($0)!=172) print $0}’ IPA1_20030906.0001
14. sed介绍
(详见632 Linux 与Unix Shell 编程指南 第10章)
可以在命令行输入sed命令,也可以在一个文件中写入命令,然后调用sed,这与awk基本相同。使用sed需要记住的一个重要事实是,无论命令是什么,sed并不与初始化文件打交道,它操作的只是一个拷贝,然后所有的改动如果没有重定向到一个文件,将输出到屏幕。因为sed是一个非交互性编辑器,必须通过行号或正则表达式指定要改变的文本行。
可以在命令行输入sed命令,也可以在一个文件中写入命令,然后调用sed,这与awk基本相同。使用sed需要记住的一个重要事实是,无论命令是什么,sed并不与初始化文件打交道,它操作的只是一个拷贝,然后所有的改动如果没有重定向到一个文件,将输出到屏幕。因为sed是一个非交互性编辑器,必须通过行号或正则表达式指定要改变的文本行。
调用sed有三种方式:在命令行键入命令;将sed命令插入脚本文件,然后调用sed;将sed命令插入脚本文件,并使sed脚本可执行。使用sed命令行格式为:
sed [选项] sed命令 输入文件
记住在命令行使用sed命令时,实际命令要加单引号。sed也允许加双引号。使用sed脚本文件,格式为:
sed [选项] -fsed 脚本文件 输入文件
要使用第一行具有sed命令解释器的sed脚本文件,其格式为:
sed脚本文件[选项]输入文件不管是使用shell命令行方式或脚本文件方式,如果没有指定输入文件,sed从标准输入中接受输入,一般是键盘或重定向结果。
sed选项如下:
n 不打印;sed不写编辑行到标准输出,缺省为打印所有行(编辑和未编辑)。p命令可以用来打印编辑行。
c 下一命令是编辑命令。使用多项编辑时加入此选项。如果只用到一条sed命令,此选项无用,但指定它也没有关系。
f 如果正在调用sed脚本文件,使用此选项。此选项通知sed一个脚本文件支持所有的sed命令,例如:sed-fmyscript.sedinput_file,这里myscript.sed即为支持sed命令的文件。
sed编辑命令
p 打印匹配行
= 显示文件行号
a\ 在定位行号后附加新文本信息
i\ 在定位行号后插入新文本信息
d 删除定位行
c\ 用新文本替换定位文本
s 使用替换模式替换相应模式
r 从另一个文件中读文本
w 写文本到一个文件
q 第一个模式匹配完成后推出或立即推出
l 显示与八进制ASCII代码等价的控制字符
{} 在定位行执行的命令组
n 从另一个文件中读文本下一行,并附加在下一行
g 将模式2粘贴到/pattern n/
y 传送字符
n 延续到下一输入行;允许跨行的模式匹配语句
只打印文件quote.txt中1到3行
sed -n ’1,3p’ quote.txt
假定要匹配单词Neave,并打印此行,方法如下。使用模式/pattern/格式,这里为/Neave/
sed -n ’/Neave/’p quote.txt
使用模式与行号的混合方式可以剔除第一行,格式为line_number,/pattern/。逗号用来分隔行号与模式开始部分。为达到预期结果,使用4,/The/。意即只在第四行查询模式the,命令如下:
sed -n ’4,/The/’p quote.txt
要打印整个文件,只需将行范围设为第一行到最后一行1,$。$意为最后一行
sed -n ’1,$p’ quote.txt
匹配任意字母,后跟任意字母的0次或多次重复,并以ing结尾,模式为/.*ing/。可以使用这个模式查询以ing结尾的任意单词。
sed -n ’/.*ing/’p quote.txt
sed替换命令
替换命令用替换模式替换指定模式,格式为:
[address[,address]]s/pattern-to-find/replacement-pattern/[g p w n]
s选项通知sed这是一个替换操作,并查询pattern-to-find,成功后用replacement-pattern替换它。
替换选项如下:
g 缺省情况下只替换第一次出现模式,使用g选项替换全局所有出现模式。
p 缺省sed将所有被替换行写入标准输出,加p选项将使-n选项无效。-n选项不打印输出结果。
w 文件名使用此选项将输出定向到一个文件。
在一堆文件中,找一个字串,然后替之以另一个
ls file | xargs sed ’s/123/456/g’ infile
要进行全局替换,即替换所有出现模式,只需在命令后加g选项。下面的例子将所有The
替换成Wow!。
sed ’s/The/Wow!/g’ quote.txt
将替换结果写入一个文件用w选项,下面的例子将splendid替换为SPLENDID的替换结果写入文件sed.out:
sed ’s/splendid/SPLENDID/w sed.out’ quote.txt
去除行尾^M符号,为此需做全局替换。设置替换部分为空。模式为:‘s/^m//g’,注意‘^M’,这是一个控制字符。要产生控制字符(^M),需遵从前面产生F1键同样的处理过程。步骤如下;键入seds/,然后按住键和v键,释放v键,再按住^键,并保持键不动,再释放两个键,最后按键。下面命令去除行尾^M字符。
sed ’s/^M//g’ dos.txt
使用s/-*//g删除横线------。
使用/^$/d删除空行。
使用$d删除最后一行
使用1d删除第一行。
使用awk{print$1}打印第一列。
cat sql.txt | sed ’s/--*//g’ | sed ’/^$/d’ | sed ’$d’ | sed ’ld’ | awk ’{print$1}’
快速一行命令
‘s/\.$//g’删除以句点结尾行
‘-e/abcd/d’删除包含abcd的行
‘s/[][][]*/[]/g’删除一个以上空格,用一个空格代替
‘s/^[][]*//g’删除行首空格
‘s/\.[][]*/[]/g’删除句点后跟两个或更多空格,代之以一个空格
‘/^$/d’删除空行
‘s/^.//g’删除第一个字符
‘s/COL\(...\)//g’删除紧跟COL的后三个字母
‘s/^\///g’从路径中删除第一个\
‘s/[]/[]//g’删除所有空格并用tab键替代
‘S/^[]//g’删除行首所有tab键
‘s/[]*//g’删除所有tab键
15. tr介绍
(详见632 Linux 与Unix Shell 编程指南 第12章)
tr用来从标准输入中通过替换或删除操作进行字符转换。tr主要用于删除文件中控制字符或进行字符转换。使用tr时要转换两个字符串:字符串1用于查询,字符串2用于处理各种转换。tr刚执行时,字符串1中的字符被映射到字符串2中的字符,然后转换操作开始。
带有最常用选项的tr命令格式为:
tr -c -d -s ["string1_to_translate_from"] ["string2_to_translate_to"] input_file
这里:
-c 用字符串1中字符集的补集替换此字符集,要求字符集为ASCII。
-d 删除字符串1中所有输入字符。
-s 删除所有重复出现字符序列,只保留第一个;即将重复出现字符串压缩为一个字符
Input-file 是转换文件名。虽然可以使用其他格式输入,但这种格式最常用。
使用tr时,可以指定字符串列表或范围作为形成字符串的模式。这看起来很像正则表达式,但实际上不是。指定字符串1或字符串2的内容时,只能使用单字符或字符串范围或列表。
[a-z] a-z内的字符组成的字符串。
[A-Z] A-Z内的字符组成的字符串。
[0-9] 数字串。
/octal 一个三位的八进制数,对应有效的ASCII字符。
[O*n] 表示字符O重复出现指定次数n。因此[O*2]匹配OO的字符串。
常用命令
删除文件中空行
tr -s ["\n"] < plane.txt
将文本文件大写转换为小写并输出至一个新文件,格式为:
cat file-to-translate | tr "[A-Z]" "[a-z]" > new-file-name
转换控制字符
tr的第一个功能就是转换控制字符,特别是从dos向UNIX下载文件时,忘记设置ftp关于回车换行转换的选项时更是如此。
猜想‘^^^^^^’是tab键。每一行以Ctrl-M结尾,文件结尾Ctrl-Z,以下是改动方法。使用-s选项,查看ASCII表。^的八进制代码是136,^M是015,tab键是011,^Z是032,下面将按步骤完成最终功能。用tab键替换^^^^^^,命令为"\136" "[\011*]"。将结果重定向到临时工作文件stat.tmp。
tr -s "[\136]" "[\011*]" < stat.tr > stat.tmp
用新行替换每行末尾的^M,并用\n去除^Z,输入要来自于临时工作文件stat.tmp。
tr -s "[\015\032]" "\n" < stat.tmp
如果需要删除文件中^M,并代之以换行。使用命令:
tr -s "\r" "\n" < input_file
将删除所有^M和^Z,代之以换行。
tr -s "[\015\032]" "[\012*]" < input_file
要删除所有的tab键,代之以空格,使用命令:
tr -s "[\011]" "[\040*]" < input_file
16. Vi的三种工作状态
1. 命令状态(CM),是Vi的初始状态,此时键盘输入视为编辑命令
2. 插入状态(IM),此状态下,键盘输入视为正文内容,按ESC切换至CM状态
3. 最后一行状态(LM),此命令状态下,按下:、/、或?键,都可以切换至LM。因为该行信息出现在显示屏的最后一行,任务包括写盘、Copy或Move指定内容、查寻等。
CM命令态指令:
1. 光标控制命令
h、j、k、l 左、下、上、右四个移动光标键
nh、nj、nk、nl 光标左、下、上、右移动n个字符
xp 当前字符与其后一个字符互换
w 光标向后移动一个字
nw 光标向后移动n个字
b 光标向前移动一个字
nb 光标向前移动n个字
H 光标移至screen首行
M 光标移至screen中间行
L 光标移至screen 尾行
+ 光标移至下一行的行首
n+ 光标下移n行,停在行首
光标上移n行,停在行首
return键 光标移至下一行的行首
^ 光标移至当前行的行首
$ 光标移至下一行的行尾
) 光标后移一个句子
光标后移n个句子
( 光标前移一个句子
n( 光标前移n个句子
} 光标后移一个段
n} 光标后移n个段
{ 光标前移一个段
n{ 光标前移n个段
2. 文件定位命令
^f 向下移一个screen
n^f 向下移n个screen
^b 向上移一个screen
n^b 向上移n个screen
^d 向下移半个screen
^u 向上移半个screen
^l 重画屏幕
G 到文件尾
nG 到文件的第n行
^G 显示光标所在的行数及文件的行数
/pattern 光标后移到字符串pattern所在位置
?pattern 光标前移到字符串pattern所在位置
n 重复最近使用的/命令,如果最近为?命令,也执行相应的/命令
N 重复最近使用的?命令,如果最近为/命令,也执行相应的?命令
3. 文件的插入、删除与修改
a 在光标后插入
A 在本行后插入
i 在光标前插入
I 在光标所在行的第一个非空字符前插入
在当前行的下一行插入,光标位置不变
在当前行的上一行插入,光标位置不变
rx 把当前字符更换成x
nrx 把n个字符换成x
R 覆盖式修改一串字符,以(ESC)结束
S 替代单个字符,以(ESC)结束
ns 替代n个字符,以(ESC)结束
cw 更改一个字,以(ESC)结束
x 删除光标位置上的字符
nx 删除光标位置开始的n个字符
dw 删除当前字
ndw 删除n个字
dd 删除当前行
ndd 删除当前n行信息
D 删除从光标开始至行尾的内容
dD 删除从光标开始至文件尾的内容
u 取消输入的最近一次命令
U 取消对当前行所实施的所有命令
J 把下一行移至当前行尾
. 重复上一次的命令
ZZ 将正在编辑的文件存盘,退出Vi程序
4. 最后一行状态下的命令
:w 将正在编辑的文件存到磁盘,不退出编辑状态
:wq 存盘并退出
:q 退出
:q! 强制退出,不存盘
:x 同:wq
:w name 将正在编辑的文件存在文件name中
:w! name 将正在编辑的文件存在文件name中,name文件中原有内容被覆盖。如果当前用户是root,对指定文件不具有写权限(例如/etc/passwd),则会强制保存,不论该用户对该文件是否有写权限。
:m, n w name 将m行至n行的内容写到name文件
:n1, n2 m n3 将n1行至n2行的内容移到n3行之后
:n1, n2 t n3 将n1行至n2行的内容复制到n3行之后
:m, n d 删m行到n行的内容
:n 光标移到第n行
:m, n s/str1/str2/g 把m行至n行之间的字符串str1换成str2
:e name 编辑新文件name
:e! name 重新编辑,丢弃已修改过的信息
:r name 将文件name中的内容插入到光标所在的位置
:! cmd 在vi内运行shell命令
:f 显示当前正在编辑的文件名和行数
:set number 在编辑文件中设置行号信息
:set nonu 取消行号信息
:set tab=n 设置TAB键为n个字符
:set all 显示所有设置的信息
:g/str 全局检索字符串str。如果是“:g/str/p”表示将包含字符串str的行一次全部显示出来。
:n n是n键,不代表数字,当vi同时打开多个文件时,用于文件间切换
ctrl+shift+6 当vi同时打开多个文件时,来回切换最近两次查看的文件。
nl n表示数字 l就是字符l,表示从当前位置后移n列,比如在行首键入“213l”表示移动至本行213列
5. 在命令行状态复制并插入正文的操作
1) 将光标移到要复制的n行信息的首行,然后按下nyy
2) 将光标移到要插入的位置
3) 按P键,在光标前一行插入复制信息
按p键,在光标后一行插入复制信息
注:按u键可以取消刚刚做的复制插入操作
在步骤1)中,要按ny表示要复制n+1行信息
6. 恢复异常丢失的文件
由于某种原因,系统突然停止工作时,正在编辑的文件会丢失,但在系统重新启动后,可以用以下命令恢复异常丢失的文件: vi -i filename
7. 举例说明
vi中, “s/str1/str2/g”将当前行全行内容中的str1替换为str2
“1,$s/str1/str2/g”将文中从第1行到底所有的str1替换为str2
“1, $s/^v^M//g”可以替换所有“^M”,其中^为同时按Ctrl键
去每行尾的所有空格,“1,$s/ *$//g”,“ *”表示连续n个空格,$表示行尾
例如某文件中有28行内容需要合并到一行,可以执行“28J”自动实现合并。
17. MAKE介绍
make可以帮助程序员一致性地编译程序,消除不必要的重复编译过程
make使用三种信息来源的重复编译过程
1) 一个用户提供的说明文件
2) 所有用到的文件名和最近修改时间
3) 填补某些空档的内部隐含规则
make命令行参数
-d 调试方式,显示make重建一个目标的原因及更新的依赖目标
-dd 显示依赖关系的检查及广泛细节的处理
-DD 显示make文件、default.mk文件、状态文件和所有隐藏依赖目标的报告
-e 为make文件内环境变量的替换赋值
-p 打印出完整的宏定义和目标说明
-P 递归地报告依赖目标,显示全部依赖层次,不重新构造任何目标
-k 当一个命令返回一个, 非零状态时,放弃在当前目标上的工作,继续执行不依赖于这个目标的其它分支
-S 取消-k选择项的作用,当某个命令返回一个非零的退出状态时,停止make处理
-t touch目标文件(使它们更新),但不执行它们相应的命令规则
target: 表示make要处理的目标入口项
macro=value 宏定义,用来在启动make程序时,给make的宏赋予新的值
make的宏处理
宏操作
= 宏定义符
$ 宏的引用
( ) { } 宏引用名定义符,当宏定义名由多于一个字符组成,并且被引用时,就可以用括号括起来,放在$的后面
$$ 对$符号宏定义的引用,它的值是字符$
+= 把这个定义符后面的值追加到左边的宏定义名上
:= 条件宏定义赋值
对make处理有特殊意义的字符
@ 如果在命令行中,制表符后的第一个字符是@,则make在执行这条命令前不打印此命令行
- 如果这个字符是命令行中制表符后的第一个字符,则make忽略由命令行返回的任何非零错误代码,继续执行
? 如果命令行以这个字符开头,则不做命令依赖检查
! 强行做命令依赖检查
% 模式匹配通配符,象shell通配符‘*’一样,%匹配零个或多个字符
make自动维护的动态宏
$@ 当前目标的名字
$? 比目标更加新的依赖目标表
$< 依赖目标文件名
$* 当前目标的基名(即去掉后缀的目标名)
$% 用于目标库的处理
宏替换的引用,可以通过模式替换来添加或修改宏定义的值的前缀与后缀,模式替换引用的格式如下:
$(macroname:p%s=np%ns)
在这里,p和s分别是宏macroname原来定义的前缀与后缀,np和ns是这个宏的新的前缀与后缀,这里%是通配符
例如: SOURCES=old_main.c old_data.c moon
OBJECTS=$(SOURCES:old_%.c=new_%.o)
%make
old_main.c old_data.c moon
new_main.o new_data.o moon
make使用的特殊功能目标
.DEFAULT: 如果在make文件中有一个入口项,没有其它目标入口项作为它的依赖目标,并且没有构造这个目标入口项的任何规则时,则执行.DEFAULT中描述的命令规则
.DONE: 如果在make文件中定义了这个目标,则在所有目标都创建好以后,make程序处理这个目标和它的依赖目标
.IGNORE: 忽略错误,当这个目标出现在make文件中时,make将忽略从执行命令返回的非零错误代码,继续执行
.INIT: 如果这个目标定义在make文件中,则在处理其它目标之前,make先创建这个目标和它的依赖目标
.KEEP_STATE: 如果这个目标出现在make文件中,则在当前工作目录中若存在状态文件make.state,则make更新这个文件,否则make产生这个状态文件
.PRECIOUS: 通常在收到中断信号时,make要删除当前的目标,如果设置了这个目标项后,在接收到中断信号后,make就不删除作为依赖目标的那些文件
.SILENT: 如果这个目标出现在文件中,则在执行命令前,make不印出命令行内容,只是默默地执行
.SUFFIXES: 用于隐含规则选择的后缀表
18. 工程中遇到的问题
/usr/lib/ld.so.1是一个非常重要的动态链接库,如果该库损坏或丢失,不仅会导致cp、mv、ftp等许多常用命令无法执行,而且即使reboot后主机也无法正常启动。解决办法如下:
将solaris系统盘插入光驱,执行boot CDROM –s,采用系统盘将主机启动至单用户模式,但此时找不到主机硬盘,需要自己逐一mount所需文件系统;
在/mnt目录下创建一个mount点目录/mnt/tmp_root,执行“mount /dev/dsk/c0t0d0s0 /mnt/tmp_root”,将主机根盘mount到/mnt/tmp_root上;
但在该mount点下,只能看到etc和bin等目录,而/usr/lib因为一般solaris安装时都采用单独分区,所以仍然找不到。解决办法是vi /mnt/tmp_root/etc/vfstab,在该目录下查看/usr/lib对应的设备名,一般缺省是/dev/dsk/c0t0d0s3,然后“mount /dev/dsk/c0t0d0s0 /mnt/tmp_root/tmp_lib”,就可以看到主机硬盘上/usr/lib目录了;
cd /mnt/tmp_root/tmp_lib,修改或替换ld.so.1为正常版本,重启后可修复系统。
setenv TERM vt100
tty erase <-(即backspace键), 只有csh支持
ctrl+u取消当前行输入
ctrl+fn+break相当于stop+A
2> 重定向stderr
/var下一般是系统Log,如果满了可以删除
查sudo、mpstat、top(查iowait)使用方法, SUN上如何启动Telnet和FTP Server
两个‘/’之间的内容用于字符串匹配,将匹配的这行内容的第三列打印出来。
阅读(2092) | 评论(0) | 转发(0) |