3.linux-shell编程总结及感悟

3.linux-shell编程总结及感悟

2023年7月26日发(作者:)

-shell编程总结及感悟linux shell编程总结

1.基本unix/linux命令(1) setuid,guid 作⽤: suid意味着如果某个⽤户对属于⾃⼰的shell脚本设置了这种权限, 那么其他⽤户在执⾏这⼀脚本时也会具有其属主的相应权限。 guid执⾏相应脚本的⽤户将具有该⽂件所属⽤户组中⽤户的权限 例:chmod 4755

(2) chmod,chown,chgrp 作⽤:修改权限 格式:chmod [who] operator [permission] filename who:u(⽂件属主) g(同组⽤户) o(其他⽤户) a(所有⽤户) operator: +(增加权限) -(取消权限) =(设定权限) permission:r(读) w(写) x(执⾏) s(⽂件属主和组set-ID) t(粘性位*) l(给⽂件加锁,使其他⽤户⽆法访问) 例:chmod ugo+rwx myfile 将myfile⽂件给u,g,o⽤户r,w,x的权限

(3) umask 作⽤:设置所创建⽂件/⽬录的缺省权限 格式:umask [value] 例: umask 022 touch file1 则file1的权限部分变为:-rw-r--r--(4) ln

格式:ln [-s] source_path target_path

(5) touch 作⽤:创建⼀个空⽂档 格式:tough myfile 注解:tough myfile将创建⼀个⽂件myfile

(6) find 作⽤:搜索⽂件 格式:find pathname -options [-print -exec -ok] -print:find命令将匹配的⽂件输出到标准输出 -exec:find命令对匹配的⽂件执⾏该参数所给出的shell命令,相应命令的格式为'command'{} ; -ok:作⽤和-exec作⽤相同。只不过每⼀步执⾏都需要⽤户的确认

-options:(主要的) -name:按⽂件名查找 -perm:按⽂件权限查找 -prune:使find命令不在当前指定的⽬录中查找 -user:按照⽂件属主查找 -group:按照⽂件所属组来查找 -mtime -n +n,按照⽂件的更改时间来查找,-n表⽰⽂件更改时间距现在n天以内,+n表⽰⽂件更改时间距现在n天以前;此外,还有-atime,-ctime选项,和-mtime选项类似 -type:查找某⼀类型的⽂件,诸如:b(块设备⽂件),d(⽬录),c(字符设备⽂件),p(管道⽂件),l(符号链接⽂件),f(普通⽂件) -size n[c]:查找⽂件长度为n块的⽂件 例: 在当前⽬录及其⼦⽬录中查找所有的"*.txt"⽂件 find . -name "*.txt" -print 在当前⽬录下查找⽂件权限位为755的⽂件,即⽂件属主可以读、写、执⾏,其他⽤户可以读、执⾏的⽂件 find . -perm 755 -print 在当前⽬录下查找除⽬录以外的所有类型的⽂件 find . ! -type d -print

⽤ls -l 命令列出所匹配的⽂件 find . -type f -exec ls -l {} ; 在/logs⽬录中查找更改时间在5⽇以前的⽂件并删除它们 find logs -type f -mtime +5 -exec rm {} ;(7)echo 作⽤:显⽰⽂本⾏或变量,或者把字符串输⼊到⽂件 格式:echo string 例: 给出提⽰符,并输⼊值给变量name echo "What's your name:c" read name (8)pg 作⽤:显⽰⽂件 格式:pg filename

(9)read 作⽤:读⼊值给变量 格式:read var 例: read name 从键盘读⼊字符到name变量(10)cat 作⽤:显⽰⽂件 格式:cat filename

(11)tee 作⽤:把输出的⼀个副本输送到标准输出,另⼀个副本拷贝到相应的⽂件中 格式:tee filename 例:who | tee 使⽤who命令,结果输出到屏幕上,同时保存在⽂件中

(12)grep(全局正则表达式) 作⽤:允许对⽂本⽂件进⾏模式查找,如果找到匹配模式,grep打印包含模式的所有⾏ 格式: grep [options] 基本正则表达式 [⽂件] 常⽤options值: -c 只输出匹配⾏的计数 -i 不区分⼤⼩写(只适⽤于单字符) -h 查询多⽂件时不显⽰⽂件名 -l 查询多⽂件时只输出包含匹配字符的⽂件名 -n 显⽰匹配⾏及⾏号 -s 不显⽰不存在或⽆匹配⽂本的错误信息 -v 显⽰不包含匹配⽂本的所有⾏ 例:grep "sort" *.doc 在当前⽬录下所有的.doc⽂件中查找字符串"sort" grep "48" data.f 抽取字符串后有⼀个键 grep '[0-9]{3}.[0-0[3}.' ipfile 要抽取其中所有的IP地址(原⽂印刷错误?) (13)awk 格式: awk [-f field-separator] 'command' input-file(s)=============================================================================== awk条件操作符===============================================================================操作符 描述 操作符 描述< ⼩于 >= ⼤于等于<= ⼩于等于 ~ 匹配正则表达式== 等于 ! 不匹配正则表达式!= 不等于

===============================================================================

awk内置变量------------------------------------------------------ARGC 命令⾏参数个数ARGV 命令⾏参数排列ENVIRON ⽀持队列中系统环境变量的使⽤FILENAME awk浏览的⽂件名FNR 浏览⽂件的记录数FS 设置输⼊域分隔符,等价于命令⾏-F选项NF 浏览记录的域个数NR 已读的记录数OFS 输出域分隔符ORS 输出记录分隔符RS 控制记录分隔符

注:awk中所采⽤的正则表达式的符号要⽐grep和sed多两个:+(匹配⼀个或多个字符),?(匹配模式出现率)

例: awk '{if($4~/Brown/) print $0}' 如果field-4包含了Brwon,打印该⾏ awk '$3 == "48" {print $0}' 精确匹配,如果field-3等于了 "48",则打印该⾏ awk '{if( $1=="p1" && $4=="p2" ) print $0}' 同时满⾜两个条件,则打印该⾏ awk '{if( $1=="p1" || $4=="p2" ) print $0}' 只要满⾜其中⼀个条件,则打印该⾏

(14)expr ⽤于计算或数值测试 格式:expr argument operator argument 例: expr 10 + 10 其结果为20 expr 30 / 3 其结果为10 expr 30 * 3 其结果为90,使⽤乘号时,必须⽤反斜线屏蔽其特定含义。 expr rr + 1 当rr⾮整数时,将返回错误,此处为"expr:non-numeric argument"

2.⽂件名的匹配

特殊的匹配符号: * 匹配⽂件名中的任何字符串,包括空字符串 匹配⽂件名中的任何单个字符串 [...] 匹配[]中包含的任何字符 [!...] 匹配[]中⾮感吧号!之后的字符

例: 显⽰所有以.doc结尾的⽂件名 ls *.doc 显⽰以cl开头,后⾯跟任何字符串,最后以.sed结尾的⽂件名 ls cl*.sed 显⽰任意两个字符开头,接着是r,后⾯跟任何字符的⽂件 ls ??r* 显⽰以i或o开头的⽂件名 ls [io]* 匹配所有以log.开头,后⾯跟随⼀个数字,然后可以是任意字符串的⽂件名 ls log.[0-9]* 匹配所有以log.开头,使⽤[!0-9]来表⽰⾮数字开头的字符串 ls log.[0-9]*

3.⽂本过滤 =============================================================================== 基本元字符集及其含义===============================================================================^ 只匹配⾏⾸$ 只匹配⾏尾* ⼀个单字符后紧跟*,匹配0个或多个此单字符[] 匹配[]内字符。可以是⼀个单字符,也可以是字符序列,⽤-表⽰范围 如⽤[1-5]代替[12345] ⽤来屏蔽⼀个元字符的特殊含义。如$ . ' " * ^ | ( ) + ?

. 匹配任意单字符pattern{n} ⽤来匹配前⾯pattern出现次数。n为次数pattern{n,}m 含义同上,但次数最少为npattern{n,m} 含义同上,但pattern出现次数在n与m之间===============================================================================

例: ^$ 匹配⼀个空⾏ ^.$ 匹配只包含⼀个字符的⾏ compu*t 匹配字符u 0次或多次,这个可匹配computer, A{2}B 匹配字母A出现两次,并以B结尾 A{2,4}B 匹配字母A出现2到4次之间

4.特定shell变量

===============================================================================$# 传递到脚本的参数个数$* 以⼀个单字符串显⽰所有向脚本传递的参数。与位置变量不同,此选项参数可超过9个$$ 脚本运⾏的当前进程ID号$! 后台运⾏的最后⼀个进程的进程ID号$@ 与$#相同,但是使⽤时加引号,并在引号中返回每个参数$- 显⽰shell使⽤的当前选项,与set命令功能相同$? 显⽰最后命令的退出状态。0表⽰没有错误,其他任何值表明有错误===============================================================================其他:$0(脚本名字) $1 $2 $3 ...$9

输⼊与输出

5.1⽂件描述符

=============================================================================== ⽂件描述符 ⽂件 0 输⼊⽂件——标准输⼊ 1 输出⽂件——标准输出 2 错误输出⽂件——标准错误

===============================================================================注: 标准输⼊是⽂件描述符0,它是命令的输⼊,缺省是键盘,也可以是⽂件或其他命令的输出 标准输出是⽂件描述符1,它是命令的输出,缺省是屏幕,也可以是⽂件 标准错误是⽂件描述符2,它是命令错误的输出,缺省是屏幕,也可以是⽂件

5.2 重定向 :<,<<,>,>>===============================================================================command>filename 把标准输出重定向到⼀个新⽂件中command>>filename 把标准输出重定向到⼀个⽂件中(追加)command 1>filename 把标准输出重定向到⼀个新⽂件中command>filename 2>&1 把标准输出和标准错误⼀起重定向到⼀个⽂件中command 2>filename 把标准错误重定向到⼀个新⽂件中command 2>>filename 把标准错误重定向到⼀个⽂件中(追加)command >>filename 2>&1 把标准输出和标准错误⼀起重定向到⼀个⽂件中(追加)command filename 2 command命令以filename⽂件作为标准输⼊,以filename2⽂件作为标准输出command <&m 把⽂件描述符m作为标准输⼊command >&m 把标准输出重定向到⽂件描述符m中command <&- 关闭标准输⼊

===============================================================================

例:##############################################################################! /bin/sh# f_desc#把⽂件描述符4指定为标准输⼊,然后打开⽂件exec 4<&0 0<

#读⼊2⾏⽂本read line1

read line2

#作为标准输⼊的⽂件描述符4被关闭exec 0<&4

#显⽰两个变量的内容echo &line1

echo &line2#############################################################################

5.3管道 : 命令1|命令2who | awk '{print $1"t"$2}'

6.条件测试

格式1:test condition格式2:[condition]

=============================================================================== ⽂件测试状态===============================================================================-d ⽬录 -s ⽂件长度⼤于0,⾮空-f 正规⽂件 -w 可写-l 符号链接 -u ⽂件有suid位设置-r 可读 -x 可执⾏===============================================================================组合测试: -a 逻辑与 -o逻辑或 !逻辑否

例: [-w -a -w echo $? 检查上⾯两个⽂件是不是都是可写的

字符串测试 string_operator 可为=(相等) !=(不相等) -z(空串) -n(⾮空串)

格式1:test "string"格式2:test string_operator "string"格式3:test "string" string_operator "string"格式4:[string_operator string]格式5:[string string_operator string]

数值测试 numeric_operator可为 -eq(相等),-ne(不相等),-gt(⼤于),-lt(⼩于),-le(⼩于等于),-ge(⼤于等于)格式1:"number" numeric_operator "number"格式2:["number" numeric_operator "number"]

7.命令执⾏顺序 && ,||, (), {}

&&格式:命令1 && 命令2说明:命令1返回真(即返回0,成功被执⾏)后,命令2才能够被执⾏例:/apps/bin⽬录将会被移到/apps/dev/bin⽬录下,如果它没有被成功的执⾏,就不会删除/apps/bin⽬录 mv /apps/bin /apps/dev/bin && rm -r /apps/bin

||格式:命令1 || 命令2说明:命令1未执⾏成功,那么就执⾏命令2例: 拷贝⽂件没成功的话,就显⽰错误. cp || echo "cp file failed!"

() {}格式:(命令1;命令2;...) {命令1;命令2;...}

8.控制流结构 if...fi,case,for,until,while,break,continue

1)返回码 观察:echo $? 退出:exit n (n为⼀数字) break n ==>跳出指定的循环个数。如break 2则跳出2个循环 continue ==>跳出循环当前步

2)流控制if...fi

if condition1 then command1 elif condition2 then command2 else command3 fi 例1:###############################################! /bin/sh# ifwrLOGFILE=o $LOGFILEif [ ! -w "$LOGFILE" ]; then echo "You cannot write to $LOGFILE " >&2fi##############################################

例2:###############################################! /bin/sh# ifcp#下⾯⽤2>&1重定向标准错误,去除了系统产⽣的错误和系统输出if cp myfile >/dev/null 2>&1 ; then echo "good copy"else echo "`basename $0`:error could not copy the files " >&2fi##############################################

例3:###############################################! /bin/sh# ifcp#将脚本参数传⼊系统命令#此处检测⽬录是否为空DIRECTORY=$1if [ "`ls -A $DIRECTORY`" = ""] ; then #也可⽤ if [$# -lt 1] 来代替判断语句 echo "$DIRECTORY is indeed empty"else echo "$DIRECTORY is not empty " >&2fi##############################################

例4:###############################################! /bin/sh# ifmkdir#将脚本参数传⼊系统命令#此处检测⽬录是否为空DIRECTORY=$1if [ "$DIRECTORY" = ""] ; then echo "Usage: `basename $0` directory to create" exit 1fiif [ -d $DIRECTORY ]then : # do nothingelse echo "The directory does exist" echo -n "Create it now? [y..n] :" read ANS if [ "$ANS" = "y" ] || [ "$ANS" = "Y" ] then echo "creating now" mkdir $DIRECTORY >/dev/null 2>&1 if [ $? != 0 ]; then echo "Errors createing the directory $DIRECTORY" >&2 exit 1 fi else : # do nothing fifi##############################################

3)case控制流 case语句为多选择语句。可以⽤case语句匹配⼀个值与⼀个模式,如果匹配成功,执⾏相匹配的命令。 格式:========================================================================== case 值 in 模式1) 命令1 .... ;; 模式2) 命令2 .... ;; esac==========================================================================注:每⼀模式必须以右括号结束,取值可以为变量或常数。匹配发现取值符合某⼀模式后,其间所有命令开始执⾏直⾄“;;”

取值将检测匹配每⼀个模式,⼀旦模式匹配,则执⾏完匹配模式相应命令后不再继续其他模式。如果⽆⼀匹配模式,使⽤星号*捕获该值,再接受其他输⼊

模式部分可能包括元字符,与在命令⾏⽂件扩展名例⼦中使⽤过的匹配模式类型相同,即*(任意字符),?(任意单字符),[..](类或范围中任意字符)

例1:###############################################! /bin/sh# casetermecho "choices are..vt100,vt102,vt220"echo -n "enter your terminal type :"read TERMINALcase $TERMINAL in vt100|vt102) TERM=vt100 ;; vt220) TERM=vt220 ;; *) echo "`basename $0`:Unknow response" >&2 echo "setting it to vt100 anyway,so there" TERM=vt100 ;;esacexport TERMecho "Your terminal is set to $TERM"##############################################

例2:###############################################! /bin/sh# caseparamif [ $# !=1 ] ; then echo "Usage:`basename $0` [start|stop|help]" >&2 exit 1fi#assign the parameter to the variable OPTOPT=$1case $OPT in start) echo "starting..`basename $0`" ;; stop) echo "stopping..`basename $0`" ;; help) ;; *) echo "Usage:`basename $0` [start|stop|help]" ;;esac##############################################

4)循环for格式==========================================================================for 变量名 in 列表do 命令1 命令2 ..... 命令ndone==========================================================================注:列表可以包含替换,字符串和⽂件名

例1:###############################################! /bin/sh# for_ifor loop in 1 2 3 4 5 #for loop in "orange red blue grey"do echo $loopdone##############################################

例2:###############################################! /bin/sh# for_lsfor loop in `ls `do echo $loopdone##############################################

例3:#for params,不使⽤in列表选项时,实际上等价于#for params in "$@" 或#for params in "$*"###############################################! /bin/sh# for_paramfor loop in "$@" # 也可以是"$*," 这可以从命令⾏中取得参数

do echo $loopdone##############################################

until(不常⽤)格式==========================================================================until 条件do 命令1 命令2 ..... 命令ndone==========================================================================例1:监视⽂件系统容量,当它达到⼀定⽔平时通知超级⽤户###############################################! /bin/sh# until_monLOOK_OUT=`df | grep /logs | awk '{print $5}' | sed 's/%//g'`echo $LOOK_OUTuntil ["$LOOK_OUT" -gt "90" ]do echo "Filesystem..logs is nearly full" | mail root exit 0done##############################################

while格式==========================================================================while 命令do 命令1 命令2 ..... 命令ndone==========================================================================

例1:从⽂件中读取数据,使⽤重定向以保证从⽂件中读取数据##########################################################################! /bin/sh | SAVEDIFS=$IFS# whileread | IFS=:while read LINE | while read NAME DEPT IDdo | do echo $LINE | echo -e "$NAMEt $DEPTt $ID"done < | done < | IFS=$SAVEDIFS#########################################################################

上⾯右边使⽤IFS将域分隔符改为;号⽽不是空格或tab键测试数据:Louise Conrad:Accounts:Acc889Peter James:Payroll:PR483#########################################################################

死循环格式while :do 命令done

例2:##########################################################################! /bin/sh# menu#set the date,user and hostname upMYDATE=`date +%d/%m/%Y`THIS_HOST=`hostname -s`USER=`whoami`#loop forever !while :do # clear the screen tput clear # here documents starts here cat <" read CHOICE case $CHOICE in 1) ls

;; 2) vi ;; 3) who ;; H|h) cat <

等我总结完了,后⾯⼜翻了⼀本书《Linux 编程命令详解》第⼆版,Richard Petersen著,梁普选,刘⽟芬 等译,2001年由电⼦⼯业出版社出版的,这本书总结得更好了。呵呵,看来,凡事都是有个过程的。

===================================================================

特殊符号的总结 1、{} ⼤括号: ⽤法⼀:通配符扩展

eg: ls my_{finger,toe}s 这条命令相当于如下命令的组合: ls my_fingers my_toes eg: mkdir {userA,userB,userC}-{home,bin,data} 我们将得到 userA-home, userA-bin, userA-data, userB-home, userB-bin,userB-data,userC-home, userC-bin, userC-data,这⼏个⽬录

⽤法⼆:可⽤于语句块的构造,语句之间⽤回车隔开。如果你想在某些使⽤单个语句的地⽅(⽐如在AND或OR列表中)使⽤多条语句,你可以把它们括在花括号{}中来构造⼀个语句块。 eg: { grep -v "$cdcatnum" $strack_file > $temp_file cat $temp_file > $strack_file echo cat -n file1 } (注:以上⼤括号中的四句命令够成了⼀个语句块)

⽤法三:参数扩展 ${name:-default} 使⽤⼀个默认值(⼀般是空值)来代替那些空的或者没有赋值的变量name; ${name:=default}使⽤指定值来代替空的或者没有赋值的变量name; ${name:?message}如果变量为空或者未赋值,那么就会显⽰出错误信息并中⽌脚本的执⾏同时返回退出码1。 ${#name} 给出name的长度 ${name%word} 从name的尾部开始删除与word匹配的最⼩部分,然后返回剩余部分 ${name%%word} 从name的尾部开始删除与word匹配的最长部分,然后返回剩余部分 ${name#word} 从name的头部开始删除与word匹配的最⼩部分,然后返回剩余部分 ${name##word} 从name的头部开始删除与word匹配的最长部分,然后返回剩余部分 (注,name为变量名,word为要匹配的字符串) ⽤法三在处理字符串和未知变量时,是很有⽤的。

2、[] 中括号: ⽤法⼀:通配符扩展: 允许匹配⽅括号中任何⼀个单个字符 eg: ls /[eh][to][cm]* 相当于执⾏ ls /etc /home(若有/eom⽬录,就相当于会执⾏ls /etc /home /eom) 注:在mkdir命令下不能扩展

⽤法⼆:⽤于条件判断符号: []符号可理解为指向test命令的⼀个软链接,所以其⽤法可完全参照test,将test位置替换为[便可。 eg: if [ "$?" != 0 ] 等价于 if test "$?" != 0 then echo "Executes error"

3、`command` 反引号:`command`与$(command)的含义相同,都是返回当前执⾏命令的结果

eg: #!/bin/sh for file in $(ls f*.sh);do lpr $file done exit 0 该例实现了扩展f*.sh给出所有匹配模式的⽂件的名字。

4、'string' 单引号 和 "string" 双引号

双引号:如果想在定义的变量中加⼊空格,就必须使⽤单引号或双引号, 单、双引号的区别在于双引号转义特殊字符⽽单引号不转义特殊字符 eg: $ heyyou=home $ echo '$heyyou' $ $heyyou ($没有转义) eg: $ heyyou=home $ echo "$heyyou" $ home (很明显,$转义了输出了heyyou变量的值) 5、$# 它的作⽤是告诉你引⽤变量的总数量是多少;

$$ 它的作⽤是告诉你shell脚本的进程号; $* 以⼀个单字符串显⽰所有的脚本传递的参数。等价于$1 $2 $3.......; $@ 与$*基本类似(参见序号7),但在数组赋值时有些不同; $? 前⼀个命令的退出码; $- 显⽰shell使⽤的当前选项; $! 最后⼀个后台运⾏的进程ID号。

6、$((...)) 语法:对括号内的表达式求值(fantaxy注:千万别乱加⼊空格)

eg: #!/bin/sh x=0 hile [ "$x" -ne 10 ];do echo $x x=$(($x+1)) done exit 0

7、shell中⼏种特殊的参数变量的引⽤

$1、$2、$3……${10}、${11}、${12}…… :表⽰脚本传⼊的的各个参数,注意当需表⽰两位数以后的参数时数字要⽤花括号括起。 $@ 列出所有的参数,各参数⽤空格隔开 $*: 列出所有的参数,各参数⽤环境变量IFS的第⼀个字符隔开

8、命令列表:

AND列表 statement1 && statement2 && statement3 && …:只有在前⾯所有的命令都执⾏成功的情况下才执⾏后⼀条命令 OR列表 statement1 || statement2 || statement3 || …:允许执⾏⼀系列命令直到有⼀条命令成功为⽌,其后所有命令将不再被执⾏ eg:#!/bin/sh touch file_one rm -f file_two if [ -f file_one ] && echo "hello" && [ -f file_two ] && echo " there" then echo "in if" else echo "in else" fi exit 0 上例的输出为: hello in else 关于AND列表与OR列表,在逻辑判断中很使⽤,下⾯就举⼀个其最常⽤的例⼦: [ condition ] && command for true || command for false: 当条件为真时,执⾏commandfor true ,当条件为假时,执⾏command for false

9、: 冒号:内建空指令,返回值为0

eg: $ : $ echo $? $ 0 while: (该语句结构可实现⼀个⽆限循环)

10、; 分号: 在 shell 中,担任"连续指令"功能的符号就是"分号"

eg:cd ~/backup ; mkdir startup ; cp ~/.* startup/.

11、# 井号:表⽰符号后⾯的是注解⽂字,不会被执⾏; * 匹配⽂件名中的任何字符,包括字符串; 匹配⽂件名中的任何单个字符。 ~ 代表使⽤者的 home ⽬录

12、 倒斜线:放在指令前,有取消 aliases(别名) 的作⽤;放在特殊符号前,则该特殊符号的作⽤消失;放在指令

的最末端,表⽰指令连接下⼀⾏(使得回车符⽆效,只起换⾏作⽤)

14、! 感叹号:通常它代表反逻辑的作⽤,譬如条件侦测中,⽤ != 来代表"不等于"

15、** 次⽅运算:两个星号在运算时代表 "次⽅" 的意思

eg:let "sus=2**3" echo "sus = $sus" $ sus = 8

发布者:admin,转转请注明出处:http://www.yc00.com/news/1690362765a338015.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信