Shell学习笔记

来源:互联网 发布:淘宝1001夜视频 编辑:程序博客网 时间:2024/06/14 17:40

1 给变量赋值时,“=”两边都不能留空格
2 Shell 的默认赋值是字符串赋值

    var=1      var=$var+1      echo $var  
打印出来的是1+1而不是2。  

3 [ -f "somefile" ] :判断是否是一个文件
[ -x "/bin/ls" ] :判断/bin/ls是否存在并有可执行权限
[ -n "$var" ] :判断$var变量是否有值
[ "$a" = "$b" ] :判断ab是否相等
4 if 语句:
if …; then

elif …; then

else

if
下面是一个简单的if语句:

        #!/bin/bash      if [ ${SHELL} = "/bin/bash" ] ; then         echo "your login shell is the bash (bourne again shell)"      else         echo "your login shell is not bash but ${SHELL}"      fi 

5 case 语句
case表达式可以用来匹配一个给定的字符串,而不是数字(可别和C语言里的switch…case混淆)。
case … in
…)
do something here ;;
esac
file命令可以辨别出一个给定文件的文件类型,如:file lf.gz,其输出结果为:
lf.gz: gzip compressed data, deflated, original filename,
last modified: Mon Aug 27 23:09:18 2001, os: Unix
我们利用这点写了一个名为smartzip的脚本,该脚本可以自动解压bzip2, gzip和zip 类型的压缩文件:

 #!/bin/bash   ftype="$(file "$1")"   case "$ftype" in   "$1: Zip archive"*)      unzip "$1" ;;   "$1: gzip compressed"*)      gunzip "$1" ;;   "$1: bzip2 compressed"*)      bunzip2 "$1" ;;   *) echo "File $1 can not be uncompressed with smartzip";;   esac  

你可能注意到上面使用了一个特殊变量$1,该变量包含有传递给该脚本的第一个参数值。也就是说,当我们运行:

smartzip articles.zip  

$1 就是字符串 articles.zip。
6 Bash只提供一维数组,并且没有限制数组大小
7 对数组元素赋值
对数组元素赋值的一般形式是:数组名[下标]=值,例如:

$ city[0]=Beijing$ city[1]=Shanghai$ city[2]=Tianjin

一个数组的各个元素可以利用上述方式一个元素一个元素地赋值,也可以组合赋值。定义一个数组并为其赋初值的一般形式是:

数组名=(值1 值2 … 值n)
其中,各个值之间以空格分开。例如:

$ A=(this is an example of shell script)$ echo ${A[0]} ${A[2]} ${A[3]} ${A[6]}this an example script$ echo ${A[8]}

由于值表中初值共有 7 个,所以 A 的元素个数也是 7 。 A[8] 超出了已赋值的数组 A 的范围,就认为它是一个新元素,由于预先没有赋值,所以它的值是空串。

若没有给出数组元素的下标,则数组名表示下标为 0 的数组元素,如 city 就等价于 city[0] 。

8 如果要列出数组中的所有元素,使用*或@作下标
9 获取数组元素的个数

$ echo ${#A[*]}

10 数值比较中常见的比较符

= -eq!= -ne(not equal)> -gt(greater than)>= -ge(greater than or equal)< -lt(less than)<= -le 

11 测试文件属性的常见参数
-r; -w; -x; -f; -d
12 字符串长度属性
-z(字符串长度为零)
-n(非零)
13 条件测试命令 test
语法:test 表达式 如果表达式为真,则返回真,否则,返回假。

$ test var1 -gt var2$ test -r filename$ test -z s1 如果串 s1 长度为零,返回真。

14 有限循环命令for…in…
语法:

for 变量名 in 字符串表
do
命令表
done
举例:

FILE="test1.c myfile1.f pccn.h"for i in $FILEdo    cd ./tmp    cp $i $i.old    echo "$i copied"done

for var in sss
sss是串行,串行是一些字符串的组合。for…in…的运作方式是把sss中的元素依次取出放入变量var中,并执行do和done之间的命令
15 判断字符的类型
范例:数字或者数字组合

能够返回结果,即程序退出状态是0,说明属于这种类型,反之不然

$ i=5;j=9423483247234;$ echo $i | grep [0-9]*5$ echo $j | grep [0-9]*9423483247234$ echo $j | grep [0-9]* >/dev/null$ echo $?0

范例:字符组合(小写字母、大写字母、两者的组合)

$ c="A"; d="fwefewjuew"; e="fewfEFWefwefe"$ echo $c | grep [A-Z]A$ echo $d | grep "[a-z]*"fwefewjuew$ echo $e | grep "[a-zA-Z]*"fewfEFWefwefe

字母和数字的组合

$ ic="432fwfwefeFWEwefwef"$ echo $ic | grep "[0-9a-zA-Z]*"432fwfwefeFWEwefwef

范例:空格或者 Tab 键等

$ echo " " | grep " "$ echo -e "\t" | grep "[[:space:]]" #[[:space:]]会同时匹配空格和TAB键$ echo -e " \t" | grep "[[:space:]]"

$ echo -e “\t” | grep “” #为在键盘上按下TAB键,而不是字符
范例:匹配邮件地址

$ echo "test2007@lzu.cn" | grep "[0-9a-zA-Z\.]*@[0-9a-zA-Z\.]"test2007@lzu.cn

16 /dev/null 和 /dev/zero 是非常有趣的两个设备,它们都犹如一个黑洞,什么东西掉进去都会消失殆尽;后者则是一个能源箱,你总能从那里取到 0,直到你退出。
17 @ 的区别
*"用「"」括起来的情况、以"12 … n@
所有参数列表。如”@"""1” “2""n” 的形式输出所有参数。
示例:

1 #!/bin/bash2 #3 printf "The complete list is %s\n" "$*"

结果:

[Aric@localhost ~]$ bash params.sh 123456 QQThe complete list is 123456 QQ
1 #!/bin/bash 2 # 3 printf "The complete list is %s\n" "$@"

结果:

[Aric@localhost ~]$ bash params.sh 123456 QQThe complete list is 123456The complete list is QQ

因为有两个参数,所以”$@”输出了两次
18 字符串的长度
范例:计算某个字符串的长度
即所有字符的个数[这计算方法是五花八门,择其优者而用之]

$ var="get the length of me"$ echo ${var}     # 这里等同于$varget the length of me$ echo ${#var}20$ expr length "$var"20$ echo $var | awk '{printf("%d\n", length($0));}'20$ echo -n $var |  wc -c20

19 字符串操作_取子串
取子串的方法主要有两种:直接到指定位置求子串,字符匹配求子串。

范例:按照位置取子串

比如从什么位置开始,取多少个字符

$ var="get the length of me"$ echo ${var:0:3}get$ echo ${var:(-2)}   # 方向相反me$ echo `expr substr "$var" 5 3` #记得把$var引起来,否则expr会因为空格而解析错误the$ echo $var | awk '{printf("%s\n", substr($0, 9, 6))}'lengthawk 把 $var 按照空格分开为多个变量,依次为 $1,$2,$3,$4,$5$ echo $var | awk '{printf("%s\n", $1);}'get$ echo $var | awk '{printf("%s\n", $5);}'me

范例:匹配字符求子串

用 Bash 内置支持求子串

$ echo ${var%% *} #从右边开始计算,删除最左边的空格右边的所有字符get$ echo ${var% *} #从右边开始计算,删除第一个空格右边的所有字符get the length of$ echo ${var##* }  #从左边开始计算,删除最右边的空格左边的所有字符me$ echo ${var#* }  #从左边开始计算,删除第一个空格左边的所有字符the length of me

可以这么理解 #和%是从左边还是右边开始计算的flag,${var#* },从左边开始计算,删除一个"*"和一个" "(空格);${var##* }从左边开始计算,删除n个"*"" "${var% *}从右边开始计算,删除一个" ""*";${var%% *}从右边开始计算,删除n个" ""*"
对于字符串的截取,实际上还有一些命令,如果 head,tail 等可以实现有意思的功能,可以截取某个字符串的前面、后面指定的行数或者字节数。例如:

$ echo "abcdefghijk" | head -c 4abcd$ echo -n "abcdefghijk" | tail -c 4hijk

20 字符串操作_查询字串
子串查询包括:返回符合某个模式的子串本身和返回子串在目标串中的位置。
范例:查询子串在目标串中的位置

貌似仅仅可以返回某个字符或者多个字符中字符第一次出现的位置

$ var="get the length of me"$ expr index "$var" t3

awk 却能找出字串,match 还可以匹配正则表达式

$ echo $var | awk '{printf("%d\n", match($0,"the"));}'5

21 字符串操作_子串替换
用 {} 运算符

$ var="get the length of me"$ echo ${var/ /_}        #把第一个空格替换成下划线get_the length of me$ echo ${var// /_}        #把所有空格都替换成了下划线了get_the_length_of_me

用 awk,awk 提供了转换的最小替换函数 sub 和全局替换函数 gsub,类似 / 和 //

$ echo $var | awk '{sub(" ", "_", $0); printf("%s\n", $0);}'get_the length of me$ echo $var | awk '{gsub(" ", "_", $0); printf("%s\n", $0);}'get_the_length_of_me

用 sed ,子串替换可是 sed 的特长

$ echo $var | sed -e 's/ /_/'    #s <= substitudeget_the length of me$ echo $var | sed -e 's/ /_/g'    #看到没有,简短两个命令就实现了最小匹配和最大匹配g <= globalget_the_length_of_me

sed 还有专门的插入指令,a 和 i,分别表示在匹配的行后和行前插入指定字符

$ echo $var | sed '/get/a test'get the length of metest$ echo $var | sed '/get/i test'testget the length of me

22 重定向
linux shell下常用输入输出操作符是:

  1. 标准输入 (stdin) :代码为 0 ,使用 < 或 <<
  2. 标准输出 (stdout):代码为 1 ,使用 > 或 >>
  3. 标准错误输出(stderr):代码为 2 ,使用 2> 或 2>>

实例:

#将错误输出信息关闭掉[chengmo@centos5 shell]$ ls test.sh test1.sh 2>&-test.sh[chengmo@centos5 shell]$ ls test.sh test1.sh 2>/dev/nulltest.sh#&[n] 代表是已经存在的文件描述符,&1 代表输出 &2代表错误输出 &-代表关闭与它绑定的描述符#/dev/null 这个设备,是linux 中黑洞设备,什么信息只要输出给这个设备,都会给吃掉 #关闭所有输出[chengmo@centos5 shell]$ ls test.sh test1.sh  1>&- 2>&- #关闭 1 ,2 文件描述符[chengmo@centos5 shell]$ ls test.sh test1.sh  2>/dev/null 1>/dev/null#将1,2 输出转发给/dev/null设备 [chengmo@centos5 shell]$ ls test.sh test1.sh >/dev/null 2>&1#将错误输出2 绑定给 正确输出 1,然后将 正确输出 发送给 /dev/null设备  这种常用<p>[chengmo@centos5 shell]$ ls test.sh test1.sh &>/dev/null#& 代表标准输出 ,错误输出 将所有标准输出与错误输出 输入到/dev/null文件

注意:

1、shell遇到”>”操作符,会判断右边文件是否存在,如果存在就先删除,并且创建新文件。不存在直接创建。 无论左边命令执行是否成功。右边文件都会变为空。

23 命令替换
语法

`command` 使用反引号

下面的例子中,将命令执行结果保存在变量中:

#!/bin/bashDATE=`date`echo "Date is $DATE"USERS=`who | wc -l`echo "Logged in user are $USERS"UP=`date ; uptime`echo "Uptime is $UP"

24
变量替换

变量替换可以根据变量的状态(是否为空、是否定义等)来改变它的值

可以使用的变量替换形式:
形式 说明

${var} 变量本来的值

${var:-word} 如果变量 var 为空或已被删除(unset),那么返回 word,但不改变 var 的值。
${var:=word} 如果变量 var 为空或已被删除(unset),那么返回 word,并将 var 的值设置为 word。
${var:?message} 如果变量 var 为空或已被删除(unset),那么将消息 message 送到标准错误输出,可以用来检测变量 var 是否可以被正常赋值。
若此替换出现在Shell脚本中,那么脚本将停止运行。
${var:+word} 如果变量 var 被定义,那么返回 word,但不改变 var 的值。

请看下面的例子:

#!/bin/bashecho ${var:-"Variable is not set"}echo "1 - Value of var is ${var}"echo ${var:="Variable is not set"}echo "2 - Value of var is ${var}"unset varecho ${var:+"This is default value"}echo "3 - Value of var is $var"var="Prefix"echo ${var:+"This is default value"}echo "4 - Value of var is $var"echo ${var:?"Print this message"}echo "5 - Value of var is ${var}"

运行结果:

Variable is not set1 - Value of var isVariable is not set2 - Value of var is Variable is not set3 - Value of var isThis is default value4 - Value of var is PrefixPrefix5 - Value of var is Prefix

25
Shell 函数返回值只能是整数,一般用来表示函数执行成功与否,0表示成功,其他值表示失败。如果 return 其他数据,比如一个字符串,往往会得到错误提示:“numeric argument required”。

如果一定要让函数返回字符串,那么可以先定义一个变量,用来接收函数的计算结果,脚本在需要的时候访问这个变量来获得函数返回值。
像删除变量一样,删除函数也可以使用 unset 命令,不过要加上 .f 选项,如下所示:
复制纯文本新窗口

$unset .f function_name

如果你希望直接从终端调用函数,可以将函数定义在主目录下的 .profile 文件,这样每次登录后,在命令提示符后面输入函数名字就可以立即调用。
26 引号
单引号字符串的限制:
单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;
单引号字串中不能出现单引号(对单引号使用转义符后也不行)。
双引号的优点:
双引号里可以有变量
双引号里可以出现转义字符
27 文件包含
像其他语言一样,Shell 也可以包含外部脚本,将外部脚本的内容合并到当前脚本。

Shell 中包含脚本可以使用:

. filename

source filename

28 IFS
内部字段分隔符(Internal Field Seprator)

0 0
原创粉丝点击