shell是一种程序

shell是一种程序;

shell扫描命令行,判断要执行的程序名称以及要传该该程序的参数;可能会执行一些特殊字符的替换;如*、?、[...]等;<>>>|等;

 

正则表达式

.:匹配任何字符;

工具

ed工具:

常用命令:

ed filename

1$p           //显示所有行;

1$s/oid/OID/g  //OID替换oid

/ ... /            //搜索前后都有空格的任意三个字符;

/               //重复搜索;

/^the/           //搜索以the开头的行;^ 表示行首匹配;

1$s/^/>>/      //在每行开头插入>>

1$s/$/>>/      //在每行末尾添加>>,$匹配行结束;

/转义字符

1,$s/..$//        //删除每行最后2个字符;

^$             //匹配不含字符的行;

/[tT]he         //搜索theThe [0123456789] = [0-9]

1$s/[aeiouAEIOU]//g    //删除所有元音字母;

一般来说,诸如*.[...]$^等正则表达式特殊符号,只有在搜索串中才有特殊意义,而在替换串中没有特殊意义;

   如果左方括号后的第一字符是^,那么匹配的意思是反过来;如:[^A-Z]匹配除大写字母以外的任何字符;

*,在构成正则表达式时,用星号来匹配0或若干个紧靠在星号前的字符;如X*

正则表达式总是寻求最大匹配,所以 .* 匹配一行;

  如果要把连字符放在方括号中作为可选的字符,必须把它放在紧跟左方括号的位置如:[-0-9][^-0-9]

X/{1,10/}     //匹配110个连续的X;前后数字可以相同;

X/{5,/}       //匹配至少5个连续的X

/(.../)         //保存匹配的字符串;把字符串包括在前加反斜杠的小括号中,可以捕获正则表达式匹配的字符串,捕获的字符串存储在编号为19的寄存器中;如:

^/(./)         //匹配行首的第一个字符,并将该字符存到1号寄存器中;用/n来引用存在寄存器中的内容;因此:

^/(./)/1       //匹配的是一行的头两个字符相同;

^/(./).*/1$    //匹配一行中的头一个字符(^.)跟最后一个字符(/1$)相同的行。

/(.../)        //把内容赋给下一个的寄存器;如

^/(.../)/(.../)   //行中头三个字符存在1号寄存器中,接着三个字符存在2号寄存器中;

1,$s//(.*/)       /(.*/)//2 /1/   //交换两个字段;其中/(.*/) /(.*/)表示匹配制表符(右小括号和反斜杠之间的字符)之间的所有字符并将它们赋给1号寄存器,匹配制表符之后的所有字符并将它们赋给2号寄存器;

 

cut工具

从数据文件或命令的输出中析取各种各样的数据域;

一般格式:cut –cchars file;如cut –c2-5 file;把每行的第二个到第五个字符取出来;

cut可以从标准输入读取;如who | cut –c1-8,18-

另一种格式:cut –ddchar –ffields filedchar是数据中分隔各字段的分隔符,默认的分隔符是制表符,fields表示要从文件file中析取出来的字段;如:cut –d: -f1,6 /etc/passwd

附:sed –n l file;会显示file中的制表符为’/t’

paste工具

把多个文件中的对应行合在一起;paste files;之间的分隔符是制表符;

如:paste names addresses numbers

-d选项:如paste –d ‘+’ names addresses numbers ;指定分隔符

-s选项:把同一个文件中的行粘在一起;

sed工具

意指流编辑器(stream editor),与ed不同,sed不能用于交互;

一般格式:sed command file;如sed ‘s/OID/oid/’ file;用oid替换OID;处理的是每行的第一个;

sed处理的是临时文件,可以这样做:

sed ‘s/OID/oid/’ file > tmp

mv tmp file

sed ‘s/OID/oid/g’ file    处理的是一行中的多出;

-n选项:从文件中析取几行;如sed –n ‘1,2p’ file      只显示前两行

p命令;sed –n ‘/OID/p’ file                         只打印包含OID的行;

d命令;sed ‘1,2d’ file                              删除掉第一和第二行

        sed ‘/oid/d’ file                            删除包含oid的行

sed ‘s/...//’ file                                     删除file文件每一行的前三个字符

tr工具

    过滤器tr用来转换来自标准输入的字符;一般格式:tr from-chars to-chars

如:tr e x < file,处理文件需要重定向;

cut –d: -f1,6 /etc/passwd | tr : ‘   

处理范围:tr ‘[a-z]’ ‘[A-Z]’ < file

-s选项:用来压缩to-chars中重复的字符;如:

tr –s ‘ :’ ‘/11’ 输入中的一个或多个连续的冒号在输出中都被替换成一个制表符;

-d选项;删除输入流中的字符;如:

tr –d ‘ ‘ < file    ==  sed ‘s/ //g’ file

grep工具

-i选项;表示不区分大小写;

-v选项;表示不包含那些行;如:grep –v ‘unix’ file

-l选项;只给出包含给定模式的文件列表,而不给出文件中的匹配行;如:grep –l ‘oid’ *.c

-n选项;显示行号;

sort工具

取出指定输入文件的每一行,将它们按升序排序;

-u选项;在输出中去除重复的行;

-r选项;颠倒排序顺序;

-o选项;指定输出文件;sort names >file == sort names –o file

但是sort names >names不行;而sort names –o names可以;

-n+1n;指定某个字段排序;字段之间用空格或制表符分隔;而可以用-t指定分隔符;如:

sort +2n –t: /etc/passwd

uniq工具

可以先排序在使用该工具;如:sort names | uniq

-d选项;找出文件中有哪些重复行;

shell编程初步

操作符前后不能加空格;

echo $variable

对于命令:x=*echo $x的执行;shell在给变量赋值时不进行文件名替换;即echo *

mv $filename ${filename}X;把文件名后面加字母X;当变量名后面要跟字母、数字或下划线时,才有必要使用大括号;

算术扩展的格式:$((expression));如echo $((i+1))

引用

单引号;告诉shell忽略所包含的所有特殊字符,双引号只要求忽略大多数,不被忽略的特殊字符:美元符号、反引号、反斜杠;

双引号中不做文件名替换;

反引号;告诉shell执行括起来的命令,等同于$(command),但不如$()好理解;

如:mail $(sort –u names) < memo

expr命令:如expr 17 /* 6 ;结果是102,需要把操作符和操作数作为分开的参数;只计算整数算术表达式,浮点数可以用awkbc命令;

参数传递

每当执行shell程序时,shell自动把第一个参数存在一个特殊的shell变量1中,第二个参数存在变量2中,以此类推;如引用第一个参数:$1 who | grep $1

$#里面存放的是命令行中的参数个数;

$*表示传递给程序的所有的参数;

shell先替换变量名,然后把命令行划分为各个参数;

几个小程序:

  查找:grep ‘‘$1’’ phonebook

  添加:echo  ‘‘$1   $2’’  >>  phonebook

        sort –o phonebook  phonebook

  删除:grep –v  ‘‘$1’’ phonebook > /tmp/phonebook

        mv /tmp/phonebook   phonebook

传递9个以上的参数:${n}

shift命令是把位置参数左移;即原来存在$2中的任何内容赋给$1,等,且$#自动减1shift也可以指定移动的个数;如:shift n

判断

if命令格式:

if commandt

then

   command

   command

   ...

fi

其中,commandt需要执行并检测退出状态,如果退出状态为0,则执行其后thenfi自己的命令;

程序退出为0时通常表示运行成功;

shell自动将最后所执行命令的退出状态设置到shell变量$?中;

当不需要命令的输出结果时,可以把输出重定向到系统的垃圾桶--/dev/null中,从它读取的是文件结束符;

如下命令: who | grep “^$user ” > /dev/null

test命令;经常用来在if命令中测试一种或几种条件;格式:test expression

如:test “$name” = fred

其中对双引号的说明:如果没有使用引号,当name为空时,test得到的参数只有两个,即=fred;而当有引号时,得到的是null=fred

检测字符串的操作符:=!=string-n string-z string;其中-n理解为检测长度是否不为0-z检测长度是否为0或是否为空;

test X”$symbol” = X  ;判断symbol是否为空;

等号操作符的优先级比-z的高;

test expression   等价于 [ expression ] ;其中[为命令,但该命令后面需要跟随]

test整数操作符:-eq -ge-gt-le-lt-ne

test文件操作符:-d 为目录、-e 存在、-f 为普通文件、-r 为进程可读文件、-s 长度不为0-w 为进程可写文件、 -x 可执行、-L 为符合化链接;

逻辑非: ;逻辑与: -a ;逻辑或:-o;其中-o优先级小于-a

小括号:()可以改变求值顺序;但小括号对shell具有特殊意义;需要转义;且需要空格隔开,如:[ /( “$count” –ge 0 /) –a /( “$count” –lt 10 /) ]

else结构;

exit命令;内部命令,立即终止shell程序的执行;exit nn为退出状态;

elif命令,格式和celse if类似;

date +%H;可以直接获得小时值;

case命令;

   case value in

   val1)    command

           command;;

   val2)    command

           command;;

   esac

case语句中可以用特殊字符指定匹配模式,就和文件名替换中的一样:?*[...]

调试程序的-x选项;sh –x后面跟程序名及其参数;

把符合|用于两个模式之间时,其作用是逻辑或;如:

hour=$(date +%H)

case “$hour” in

0? | 1[01] ) echo “ morning”;;

1[2-7] )   echo “afternoon”;;

*    )    echo “evening”;;

esac

空命令; 

&& || 命令,和c类似;

循环

for命令格式:首先word1赋值给var,执行循环体,让后...

for var in word1 word2 ... wordn

do

command

...

done

shell允许在for命令的词列表中使用文件名替换;如:for file in file[1-4]for file in *

$@$*类似,只是$@可以在前后加双引号;

for命令后面不带列表时;即 for var 等同于 for var in “$@”

while循环,先执行command1,并检测其退出状态,如果为0,就执行command

while command1

do

command

...

done

while常与shift命令结合使用,以处理命令行中键入的参数个数可变的情况;

while [“$#” –ne 0 ]

do

echo “$1”

shift

done

until命令;格式同while,当command1退出状态为0时,循环结束;

发送邮件:echo “$user has loggde on” | mail fred

break命令同c的;且有break n;退出最里层的n重循环;

continue命令也同c的,且有continue n使最里层的n重循环后面的所有命令都被跳过

可以给循环重定向其输出输入,循环中的单个命令也可以再重定向;

终端:/dev/tty,它总表示你的终端;

如在单行或命令行中输入循环,格式如:for i in 1 2 3 4; do echo $i; done

其他循环及判断如上;

getcmd命令;

getopts命令;命令设计目标是在循环中运行,每次执行循环,getopts就检查一下命令行参数;同cgetopts;格式:getopts options variable;选项后面如果有:,则表示选项后面需要参数,并把该参数存入一个特殊的变量:OPTARG;每处理一次OPTIND会加1

数据的读入和显示

read命令;

格式:read variablesshell从标准输入读入一行数据,并把读入的词一次赋给变量,如果读入的多,就把剩余的赋给最后一个变量;

echo命令会自动在其最后一个参数之后加上行结束符;

echo解释的医学特殊字符:/b 退格;/c 行尾不带行结束符;/f 换页;/n 换行;/r 回车;/t 制表符;等;

basename命令:给出参数的基本文件名;如 basename /usr/bin/file 得到file

一个小拷贝程序:p204

numargs=$#

filelist=

copylist=

while [ “$#” –gt 1 ]

do

filelist=”$filelist $1”

shift

done

to=”$1”

if [“$numargs” –lt 2 –o “$numargs” –gt 2 –a ! –d “$to” ]

then

echo “Usage: mycp file1 file2”

echo “      mycp file(s) dir”

exit 1

fi

for from in $filelist

do

if [ -d “$to” ]

then

    tofile=”$to/$(basename $from)”

else

    tofile=”$to”

fi

if [ -e “$tofile” ]

then

    echo “$tofile already exits; overwrite (yes/no) ? /c”

    read answer

    if [ “$answer” = yes ]

    then

        copylist=”$copylist $from”

    fi

else

    copylist=”$copylist $from”

fi

done

if [ -n “$copylist” ]

then

   cp $copylist $to

fi

shell变量$$,保存当前进程的ID

cat filename |

while read line

do

echo “$line”

done

上面通过管道把cat输出给while循环;

read命令-r选项,防止它解释反斜杠字符;

printf命令:格式:printf “format” arg1 arg2 ...

printfecho不同,它不会自动向输出添加换行符;然而可以理解”/n”

环境

shell就是登陆shell为了运行期望的程序而执行的全新的shell;新shell运行时,是在自己是环境中运行,使用它自己的局部变量集;

局部变量

变量一旦被导出,对所有后续执行的子shell,该变量都是导出变量,包括孙子shell;语法:export variables;

导出变量的清单都复制给子shell;仅仅是复制;

export –p,就会得到shell所导出的所有变量的清单;

shell作为命令提示符显示的字符$存在变量PS1中,可以改变它;辅助命令提示符>存在于变量PS2中;

登陆系统后的宿主目录存在特殊变量:HOME中;当cd不带参数时,就使用该变量;

PATH指定是执行命令时shell要搜索的目录;这些目录彼此用冒号分隔;执行命令时也可以直接给命令指明路径;

CDPATH变量跟PATH变量相似;

.命令;读作”dot”;格式:. file;它的作用是在当前shell中执行file中的内容,也就是由当前shell来执行file中的命令,不产生子shell来执行这些程序;

一个应用,. mysql,如一个mysql中的内容:

HOME=/usr2/data

BIN=$HOME/bin

PATH=$PATH$BIN

 

PS1=”mysql> ”

export HOME BIN PATH PS1

/usr/bin/sh

exec命令:执行程序,格式 exec program;或重新分配标准输出输入,

格式 exec < fileexec > report;

可以把命令组成一组,用小括号或大括号括起来;小括号形式是用子shell执行这些命令;大括号则在当前shell中执行;且大括号的左括号后必须有个空格,最后一条命令后必须有分号;这样一组的命令可以使用&在后台进行执行;

给子shell传递变量的另一种方法,如DBHOME=/usr/data DBID=326 dbrun

(DBHOME=/usr/data; DBID=326; export DBHOME DBID; dbrun)

profile文件;两个profile文件

在登录系统时,当shell显示命令提示符并等待你键入第一条命令时;在这之前,登录shell执行了系统中两个特殊文件:profile;一个是/etc/profile,该文件有系统管理员设置,通常做一些诸如检查是否有邮件、设置默认的创建文件的掩码、给某些标准导出变量赋值、以及任何管理员希望每当用户登录时都需要执行的命令;一个是宿主目录下面的.profile,当你得到账户时,系统给的一个默认文件,里面可以是一些环境变量,然后导出这些变量;

这两个文件是登陆shell执行的;(就如. /etc/profile   . .profile)

一个关于终端的变量:TERM变量;

date命令和一些c标准库函数要用到TZ变量来确定时区信息;如:TZ=EST5 date

 

深入参数

参数替换

${parameter}  如因为参数名后面的字符可能会导致冲突,可以把参数名放在大括号中,如mv $file ${file}x

${parameter:-value};该结构意思:如果parameter不为空,就替换它的值,否则就替换为value

${parameter:=value};当parameter为空时,不但使用value,还把它赋给parameter;但不能给位置参数赋值;这些不能作为单独的命令;

${parameter:?value};如果parameter不为空,shell就替换它的值;否则shell就把value写入标准错误,然后退出;

${parameter:+value};如果parameter不为空,则中结构替换为value;否则什么也不替换;

以上的value都可以是命令替换;如:WORKDIR=${DBDIR:-$(pwd)}

模式匹配结构:四种参数替换结构;每种结构都有两个参数:变量名以及模式;

${variable%pattern}shellvariable中查找,看它是否以给定的模式结尾,如果是就从命令行中把variable的内容从右边去掉最短的匹配模式;

${variable%%pattern};从右边去掉最长的匹配模式,不过只有在pattern中用了*时才是;人、否则同%;

${variable#pattern};从左边去掉;

${variable##pattern};从左边去掉最长的匹配pattern中的内容;

上面结构中都不对变量本身作修改;只有命令行中替换的内容受影响;

如检测存在file中的文件名是否以.o这两个字母结尾:if [ ${file%.o} != $file ]

$0变量:shell自动把程序名存在一个特殊的变量$0中;

set命令:设置各种shell选项,以及给位置参数$1$2等重新赋值;

-x选项;打开shell的跟踪模式;set –x

+x选项;关闭跟踪模式;可以插入到程序里面;

命令行set a b c;把这些值赋给了$1$2等,以及把个数赋给$#

--选项;它让set不要把行中后面的其他字符作为选项;

IFS变量;代表内边字段分隔符;即空白字符;可以用:echo “$IFS” | od –b查看;可以给它赋值;

readonly命令用来说明以后不能修改其值的变量;变量的只读属性不能传递给子shell;且一旦为只读就没办法将它撤消;

readonly –p;得到只读变量的清单;

unset命令;把变量从环境中删除;但不能删除只读变量;

杂项

eval命令;eval command-lineshell在执行命令行之前扫描它两次;

如:pipe=”|”

    eval ls $pipe wc -l

第一次扫描命令行时,它替换出pipe的值|,接着eval使它再次扫描命令行,这时shell|作为管道符号了;

如:eval echo /$$#

wait命令;

wait process-idprocess-id如为空,则shell等待所有的子进程完成;

$!变量保存shell最后一个送到后台的进程标志值;

trap命令;在按下删除键后,终端向运行中的程序发送信号,程序可以决定接受到信号后应该采取的行动,可以通过trap命令实现;trap commands signals

常用信号编号:0 退出shell1 挂起;2 中断(DeleteCtrl+C)15 软件结束信号(kill发出)

如:trap “rm $WORKDIR/work1$$ $WORKDIR/dataout$$; exit” 1 2

trap “” 2;忽略信号,如果忽略一个信号,则所有的子shell也忽略该信号;如果设置一个信号的动作,而子shell还是采取默认动作;

trap 1 2;把收到信号12时的动作恢复为默认设置;

>&表示输出重定向到跟其后的文件描述符相关联的文件;

如标准输出和标准错误集中到一个文件:command > foo 2>>foo;或command >foo 2>&1

把标准输出定向到foo,把标准错误重定向到标准输出(因为它已经重定向到foo)

>&-的作用是关闭标准输出,如果在前面加上文件描述符,就关闭与之关联的文件;<&-

<<;内联输入重定向;如command <<word;格式把<<跟在命令之后,shell将把其后的各行作为command的标准输入,直到遇上仅包含word的行;如wc –l <<ENDOFDATA

shell对重定向的输入数据做参数替换、执行反引号中的命令并识别反斜杠字符。然而其他的特殊字符如*|以及等都忽略掉。如果在这些数据行中有美元符号、反引号、反斜杠字符,而且不希望shell来处理这些字符,可以在他们前面加上一个反斜杠字符;如果希望shell把所有的输入行都原样保留,可以在跟在<<之后的词之前加上反斜杠;如果紧接着<<的第一个字符是连字符-shell就会把数据行中开头的制表符去掉;p274

内联输入重定向特性的最大用处之一是创建shell档案文件;

p378有个档案文件的例子不是很了解;

函数;格式:name(){ command; ... command; }

unset –f name;把一个函数的定义从shell中去掉;

函数中exit命令不只是结束函数,也结束调用函数的shell程序;

return命令只是结束函数;

type命令;如:type pwd;查看命令的来源,或类型;

 

!#;如果在一个文件中行首,那么该行余下的部分指明了对文件的一个解释;

ENV文件;当你启动shell时,它所做的第一件事情就是在你的环境中寻找名为ENV的变量,如果找到了,则执行由ENV所指定的文件;这非常类似于登陆时执行的配置文件;

行编辑器模式;set –o vi set –o emacs;打开vi模式或emacs模式;

命令历史记录列表保存在你的宿主目录下的文件.sh_history

vi的一些命令:ia是插入模式;esc后进入命令模式:wbxhl$0kj/

查看记录的命令:history,可以跟数字;

fc命令:可以为历史记录中的一条或多条命令启动编辑器,或直接将历史命令列在终端上;如:fc –l 100 122;将命令100到命令122写入标准输出;

fc –n –l -20;将最后20条命令写入标准输出;

alias命令;用例定义别名;如:alias name=stringalias ll=’ls –l’unalias name;删除别名;

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值