Shell学习笔记

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" ] :判断$a和$b是否相等  
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 $FILE do 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>" #<tab>为在键盘上按下TAB键,而不是字符<tab>
 范例:匹配邮件地址

  
  
$ echo "test2007@lzu.cn" | grep "[0-9a-zA-Z\.]*@[0-9a-zA-Z\.]" test2007@lzu.cn 16 /dev/null 和 /dev/zero 是非常有趣的两个设备,它们都犹如一个黑洞,什么东西掉进去都会消失殆尽;后者则是一个能源箱,你总能从那里取到 0,直到你退出。

17 $* 和 $@ 的区别

$* 
所有参数列表。如"$*"用「"」括起来的情况、以"$1 $2 … $n"的形式输出所有参数。 
$@ 
所有参数列表。如"$@"用「"」括起来的情况、以"$1" "$2" … "$n" 的形式输出所有参数。

示例:

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

结果:

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

结果:

[Aric@localhost ~]$ bashparams.sh 123456 QQ
The complete listis 123456
The complete listis QQ
因为有两个参数,所以"$@"输出了两次

18 字符串的长度

范例:计算某个字符串的长度

即所有字符的个数[这计算方法是五花八门,择其优者而用之]


  
  
$ var="get the length of me" $ echo ${var} # 这里等同于$var get the length of me $ echo ${#var} 20 $ expr length "$var" 20 $ echo $var | awk '{printf("%d\n", length($0));}' 20 $ echo -n $var | wc -c 20 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))}' length

awk 把 $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 4 abcd $ echo -n "abcdefghijk" | tail -c 4 hijk 20 字符串操作_查询字串

子串查询包括:返回符合某个模式的子串本身和返回子串在目标串中的位置。

范例:查询子串在目标串中的位置

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


  
  
$ var="get the length of me" $ expr index "$var" t 3

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 <= substitude get_the length of me $ echo $var | sed -e 's/ /_/g' #看到没有,简短两个命令就实现了最小匹配和最大匹配g <= global get_the_length_of_me

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


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

22 重定向

linux shell下常用输入输出操作符是:

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

实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#将错误输出信息关闭掉
[chengmo@centos5 shell]$ls test.sh test1.sh 2>&-
test.sh
[chengmo@centos5 shell]$ls test.sh test1.sh 2>/dev/null
test.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/bash DATE=`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/bash

echo ${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 var
echo ${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 set 1 - Value of var is Variable is not set 2 - Value of var is Variable is not set 3 - Value of var is This is default value 4 - Value of var is Prefix Prefix 5 - 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

转载于:https://my.oschina.net/u/2519784/blog/601081

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值