shell编程备忘录

这是自己在从学习shell到实际编一些小脚本的过程中,总结的一些shell知识,这些知识可能都能在其他地方看到,只是我把它们整合了一下,其中包含shell一些基本但又极其重要的部分,希望分享给大家作为编写shell时的手边备忘。


由于这些是从学习shell开始到现在,偶尔逐步追加的一些points,不连续,缺乏连贯性和逻辑性,限于本人level,难免其中有些小bug,若发现,还望指出。


shell三种流程控制结构(判断,分支,循环)


#判断


if [condition]


then


  cmd-list


elif [condition]


then


  cmd-list


else


  cmd-list


fi


注:elif [condition]; then 部分是可选的,是0个或多个关系:{elif [condition]; then}*


------------------------------------------------------我是分隔线------------------------------------------------


#分支


case var in


  1)cmd-list;;


  2)cmd-list;;


  3)cmd-list;;


  *)default-list;


esac


注:经常与它配套使用的还有一种类似控件选择分支的结构叫select,在此不多介绍了,常与case结合使用的一种特殊循环


------------------------------------------------------我是分隔线------------------------------------------------


#三种循环


for var in [value-list]


do


  cmd-list


done


------------------------------------------------------我是分隔线------------------------------------------------


while [condition]


do


  cmd-list


done


------------------------------------------------------我是分隔线------------------------------------------------


until [condition]


do


  cmd-list


done


------------------------------------------------------我是分隔线------------------------------------------------


流程控制是shell编程最基本的地方,在此再贴上这几种结构的例子:


#!/bin/sh


#if.sh file


echo "Input a number:"


read var


if [ -z $var ]


then


echo "var is empty, you input nothing"


elif [ $var -le 5 ]


then


echo "$var low equal than 5"


else


echo "$var greater than 5"


fi


------------------------------------------------------我是分隔线------------------------------------------------


#!/bin/sh


#case.sh file


case $# in


0) echo "No parameter.";;


1) echo "1 parameter:$1";;


2) echo "2 parameters:$1 $2";;


*) echo "More than 2 parameters:$@";;


esac


------------------------------------------------------我是分隔线------------------------------------------------


#!/bin/sh


#for.sh file


for var in A B C


do


echo "var is $var"


done


------------------------------------------------------我是分隔线------------------------------------------------


#!/bin/sh


#while.sh file


echo "Please input sth to echo:"


while read var


do


echo "$var"


done


------------------------------------------------------我是分隔线------------------------------------------------


#!/bin/sh


#until.sh file


echo "Please input sth to echo:"


until read var; [ -z "$var" ]


do


echo "$var";


done


------------------------------------------------------我是分隔线------------------------------------------------


0.shell变量


<1>等号两边不能有空格


<2>无数据类型概念,全部变量都理解为字符型


<3>变量替换


a=2334 # 整型.


let "a += 1" # 仅支持bash


echo "a = $a " # a = 2335


echo # 还是整型.


b=${a/23/BB} # 将"23"替换成"BB".


<4>'string' 单引号 (single quote, hard quote)


被单引号用括住的内容,将被视为单一字串。在引号内的代表变数的$符号,没有作用,也就是说,他被视为一般符号处理,防止任何变量替换。


heyyou=homeecho '$heyyou' # We get $heyyou


<5>"string" 双引号 (double quote, soft quote)


被双引号用括住的内容,将被视为单一字串。它防止通配符扩展,但允许变量扩展。这点与单引数的处理方式不同。


1.函数间接引用传递,eg.


Say="Hello";


Hello="World!";


echo ${Say};


echo ${!Say};


输出:HelloWorld!


2.特殊变量


<1>$*变量: 存储命令行键入的全部参数$*=$1c$2c... c is the first char of IFS, if IFS is unset, c=' ', else if IFS is null, c is null too.


<2>$@变量: 命令行键入参数列表,注意与$*的区别$@="$1" "$2" ...


<3>$#变量: 存储命令行键入的参数个数


<4>$?变量: 退出状态存储的变量--系统自动(foreground pipeline)


<5>$-变量: current option flags


<6>$$变量: 存储shell的进程ID,如果在子进程中,该变量是其父shell的进程ID


<7>$!变量: 存储系统最后一个进程的id,eg. command &后台异步的进程(background & asynchronous)


<8>$0变量: 存储程序名


<9>${n}变量: 当传递的参数大于9的时候,必须使用这种方式来存取第10、11、…参数


<10>$_变量:


3.关于命令的执行


三种方法执行shell脚本:


<1>重定向给sh:


   $:sh < script.sh


<2>传递脚本文件给sh:


   $: sh script.sh


<3>直接执行script.h:


   $: chmod a+x script.sh


   $: ./script.sh


前两种方法的优点是,script.sh不一定是可执行的,最后一种却需要执行权限,优点是直观。


4.管道与标准输入输出:


需要参数的命令如果不指定参数,会从标准输入中获得输入;==>管道(主要第一个程序向标准输出写入输出,第二个程序从标准输入读取输入,就可以建立管道)


5.查找并替换


sed 's/Fine/FINE/g' test.txt > temp 修改保存在临时文件 (g为全局选项,否则只替换每行的第一个单词)


mv temp test.txt 更新原来文件


将test.txt 中的Fine替换为FINE。


6.从1到多个文件中搜索特定字符


grep -n 'shell' ed.cmd 从文件ed.cmd中找出shell所在的行(grep -i 参数忽略大小写 -v 不包含选项 -n 包含行数选项)


7.排序


sort 文件名


-u 去处重复行


-r 反序排序


-o 输出给同名文件 (直接保存到原文件中)


+1n 跳过一个字段(空格或制表符为单词间隔)


-t:以":"为跳跃间隔符


sed -n '/shell/p' ed.cmd 同结果


cat /etc/passwd | sort -t: -k3.1,3,4 -nr #逆序将用户ID排序


8.查找重复行


uniq test.txt


-d 找出重复的行


-c 统计重复行的次数


9.算数扩展运算


$((算数表达式/逻辑表达式))


10.引用


单引号(hard quote):shell严格的忽略全部单引号之间的字符


双引号(soft quote):shell不忽略$、反斜杠、反引号


反斜杠:等价单引号,对一个字符有效,适用于去掉特殊意义的字符,以免被shell解析(\c与'c' 等价)


放在一行最后,可以用于忽略换行符,也就是续行


11.命令替换


$()或者反引号``引起来,在子shell中执行命令,eg.


$(pwd) `pwd`


12.参数传递


从命令行接受参数,shell自动把从命令行中接受的第一个参数存放在第一个变量,第二个放第二个,……


从变量出现的位置开始算,同名算一个


shift命令每执行一次,变量的个数($#)减一,而变量值提前一位


当只有0个参数时,执行命令会报错


shift n:执行n次shift


eg. shift.sh


#!/bin/sh


while [ $# -ne 0 ]


do echo $1


done


结果:./shift.sh file1 file2 file3 将输出file1死循环


file1


file1


file1


......


eg. shift.sh


#!/bin/sh


while [ $# -ne 0 ]


do echo $1


shift #add this command


done


结果:./shift.sh file1 file2 file3 将依次输出参数


file1


file2


file3


13.垃圾桶


/dev/null


对于某些输出到标准输出的命令,如果不想输出,则可以重定向输出到系统垃圾桶中


14.逻辑操作符


! 逻辑非


-a 逻辑与


-o 逻辑或


15.空命令


:


16.格式化输出


printf命令


可以格式化的显示


printf "format" arg1 arg2 …


%表参数:


echo自动添加换行符,printf不会 "\n"可以进行换行


17.导出变量


export variables


父shell利用导出变量,能够将值复制给子shell,对所有后续子shell有效


export -p :清单


18.exec命令


exec program :启动一个新的shell代替当前的shell,所以这个语句后面的任何命令将无效(但可以用子shell去执行$exec, 如使用括号(exec pwd))


19.( … )和{ …; }结构


( … ) 子shell执行命令(可以没有空格,末尾可以没有分号)


{ …; } 当前shell执行命令(必须有空格,末尾必须有分号)


但命令串执行()和{}有区别:


A,()只是对一串命令重新开一个子shell进行执行


B,{}对一串命令在当前shell执行


C,()和{}都是把一串的命令放在括号里面,并且命令之间用;号隔开


D,()最后一个命令可以不用分号


E,{}最后一个命令要用分号


F,{}的第一个命令和左括号之间必须要有一个空格


G,()里的各命令不必和括号有空格


H,()和{}中括号里面的某个命令的重定向只影响该命令,但括号外的重定向则影响到括号里的所有命令


20.深入参数


<1>参数替换


${parameter}


mv $file ${file}x :改名,给文件名增加X


${parameter:-value}:parameter 不为空,则替换值


${parameter:=value}:当parameter 不为空,不但使用value,而且赋值给parameter;不能用在位置参数上(也就是parameter不能使数字)


典型用法:测试导出变量是否设置了值,如果没有,就将它设为默认值


${parameter:?value}: 不为空替换,否则把value写入标准错误,然后退出


${parameter:+value}: 不为空替换,否则啥也不替换


<2>模式匹配


<3>set命令


设置各种shell选项,或者给位置参数$1,%2等重新赋值


<4>IFS变量


<5>readonly命令


<6>unset命令


21.函数


name () {command; … command;}


函数在定义shell中有效。


可以将一些常用的函数放在一个单独的文件中,然后通过点(.)来调用,那样,就可以在shell编程中使用。


<1>unset -f name


将函数定义去除


<2>return命令


exit会结束调用的shell,用return来结束函数运行


22.杂项


<1>eval命令


shell双次稍描命令行


<2>wait命令


wait process-id:省略进程号的话默认全部子进城


<3>trap命令


trap commands signals:


常用信号编号:


0-退出shell


1-挂起


2-中断(例如Delete、Ctrl+C键)


15-软件结束信号(默认由kill发出)


<4>深入I/O


<$-:关闭标准输出


>&-:关闭标准输入


<5>关于shell语句末的分号


shell中分号(;)仅起分隔语句的作用,如果一行仅有一条shell语句,则不用加分号,


但如果一行写有多条语句,则语句间要用分号隔开。比如if语句后面的then如果同if


在同一行就必须用;,eg. if [ -z $arg ]; then


<6>bash中有一个特性,通过declare a定义的a为整数


23.引用回溯命令的参数!^ !$ !!:n


!^: previous command's first arguments


!$: previous command's last arguments


!*: previous command's all arguments list


!!:0 --> previous command name


!!:1 --> previous command's first argument


!!:n --> previous n-th argument


原文:http://q16964.bokee.com/503603442.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值