注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

notes

@-@

 
 
 

日志

 
 
 
 

Shell(Bash)学习笔记zz  

2009-09-02 15:03:12|  分类: UNIX |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

一.变量

变量直接赋值,不用提前声明。

Js代码
  1. var="Hello"  
  2. var=Hello  
  3. var='Hello'  
var="Hello"  var=Hello  var='Hello'  
 

注意几点:

1.变量和值之间不能有空格,否则解释器会认为是几个命令。很多程序员的习惯是在=号两边留空格为了好看,但这点在shell中行不通。

2.字符串不必用"号或者',上面的几种赋值方式是等价的。除非字符串之间有空格的时候。

如:

Js代码
  1. var="Hello World"  
var="Hello World"
 

这时候就需要用引号。

3.

Js代码
  1. var=  
var=
 这样的语句也是合法的,表示var的值为空。

 

4.使用变量的时候需要在变量前面加上$符号。这一点php程序员比较熟悉。

如:

Js代码
  1. echo $var  
echo $var
 

这也就是为什么shell中的字符串不必用引号的原因。你如果直接运行

Js代码
  1. echo var  
echo var
 

系统会将var当作字符串,而不是变量处理。在变量前加上$号还有个好处就是在字符串中输出变量的时候,直接在字符串里面用变量就行。

如:


Js代码
  1. var=World  
  2. var2="$var World"  
  3. echo $var2  
var=World  var2="$var World"  echo $var2
 

 

但与php不同的是变量赋值的时候不用加$符号。因为shell中没有==这个符号,判断相等也是用=号。如果赋值的时候加上$号,会产生混淆。

还有一点要注意的就是单引号(')字符串 中的变量不会被替换。

 

Js代码
  1. var=World  
  2. var2='$var World'  
  3. echo $var2  
var=World  var2='$var World'  echo $var2

上面的语句输出结果:$var World

这个可以用来输出$等特殊符号,而不用担心字符被当作变量替换。

二.语句

1.shell的语句不必用;号结束,除非是同一行写几个语句的时候。

2.shell中的语句块不用{}号扩起来。if语句一般就用fi表示结束。当然这个也有特例,后面会提到。

3.if语句
Js代码
  1. if [ condition ]  
  2. then   
  3.     action  
  4. elif [ condition2 ]  
  5. then   
  6.     action2  
  7. .  
  8. .  
  9. .  
  10. elif [ condition3 ]  
  11. then   
  12. else  
  13.     actionx  
  14. fi  
if [ condition ]  then       action  elif [ condition2 ]  then       action2  .  .  .  elif [ condition3 ]  then   else      actionx  fi

需要注意的是shell中没有elseif,而是elif(这个缩写也太变态了吧,有必要么?).

每个或者elif后跟着then,并且要换行或者用;分开。then可以和后面的action在一行。

 

3.for循环

Js代码
  1. var="one two three four"  
  2. for x in $var  
  3. do  
  4.      echo $x  
  5. done  
var="one two three four"  for x in $var  do       echo $x  done

 for循环用do  和 done表示开始结束,不要举一反三,认为是用 rof结束。

4.while和util循环

 

Js代码
  1. while [ condition ]  
  2.  do  
  3.      statements  
  4.  done  
while [ condition ]   do       statements   done
 
Js代码
  1. until [ condition ]  
  2.  do  
  3.      statements  
  4.  done  
until [ condition ]   do       statements   done
 

 

 

5.条件语句

shell中的条件语句用[]号括起来,用于if,while,until等结构。

 条件判断用=号,而不是==号。条件语句与[] 号之间要有空格分开。

如:

 

Js代码
  1. gender="boy"  
  2. if [ "$gender" = "girl" ]  
  3. then  
  4.       echo 'Welcome!'  
  5. else  
  6.       echo 'We only welcome girl.'  
  7. fi  
gender="boy"  if [ "$gender" = "girl" ]  then        echo 'Welcome!'  else        echo 'We only welcome girl.'  fi

还 有要注意的是条件语句中=号两旁要有空格分开,否则shell会将条件语句整个作为一个字符串处理,条件永远为真。条件语句中的变量最好用"号引起来,否 则如果该变量中有空格,shell就会报too many arguments错误。如果变量正好为空,则会报 =: unary operator expected.错误。因为变量为空的话,条件语句少了一边,当然会出错。所以,将字符串变量用双引号括起来是shell编程的好习惯,尤其在条件语句中。

 

其他的比较符号,如 >,<,不能直接在条件语句中使用,因为>号在shell中有特殊含义。下面是shell的比较运算符号表示方法:

 

Xml代码
  1. 算术比较运算符  
  2.   
  3. num1-eq num2    等于  [ 3 -eq $mynum ]  
  4. num1-ne num2    不等于 [ 3 -ne $mynum ]  
  5. num1-lt num2    小于  [ 3 -lt $mynum ]  
  6. num1-le num2    小于或等于   [ 3 -le $mynum ]  
  7. num1-gt num2    大于  [ 3 -gt $mynum ]  
  8. num1-ge num2    大于或等于   [ 3 -ge $mynum ]  
算术比较运算符    num1-eq num2  等于 [ 3 -eq $mynum ]  num1-ne num2  不等于 [ 3 -ne $mynum ]  num1-lt num2  小于 [ 3 -lt $mynum ]  num1-le num2  小于或等于 [ 3 -le $mynum ]  num1-gt num2  大于 [ 3 -gt $mynum ]  num1-ge num2  大于或等于 [ 3 -ge $mynum ]
 
Xml代码
  1. 字符串比较运算符   
  2.   
  3. -z string   如果 string长度为零,则为真   [ -z "$myvar" ]  
  4. -n string   如果 string长度非零,则为真   [ -n "$myvar" ]  
  5. string1string2    如果 string1与 string2相同,则为真   [ "$myvar" = "one two three" ]  
  6. string1!= string2   如果 string1与 string2不同,则为真   [ "$myvar" != "one two three" ]  
字符串比较运算符     -z string  如果 string长度为零,则为真  [ -z "$myvar" ]  -n string  如果 string长度非零,则为真  [ -n "$myvar" ]  string1= string2  如果 string1与 string2相同,则为真  [ "$myvar" = "one two three" ]  string1!= string2  如果 string1与 string2不同,则为真  [ "$myvar" != "one two three" ]

6.case 语句

 

Js代码
  1. gender="boy"   
  2. case "$gender" in  
  3.       boy)  
  4.             echo "We only welcome girl."  
  5.             ;;  
  6.       girl)  
  7.             echo 'Welcome !'  
  8.             ;;  
  9.       *)  
  10.             echo "unknow."  
  11.             ;;  
  12.  esac    
gender="boy"   case "$gender" in        boy)              echo "We only welcome girl."              ;;        girl)              echo 'Welcome !'              ;;        *)              echo "unknow."              ;;   esac  

case语句的语法比较怪,乍一看比较别扭。每个pattern用 半括号括起来,用;;结束。

三.算术

shell 默认是用来处理字符串的,所以如果你直接运行:

Js代码
  1. echo 1+1  
echo 1+1

 它会直接输出1+1,而不会输出2。 如果需要计算表达式的值,则只需用"$((" 和 "))"将表达式 括起。

Js代码
  1. echo $((1+1))  
echo $((1+1))
 

四.函数

Js代码
  1. add(){  
  2.     result=0  
  3.     for n in $*  
  4.     do  
  5.         result=$(($result+$n))  
  6.     done  
  7.     return $result  
  8. }  
add(){      result=0      for n in $*      do          result=$(($result+$n))      done      return $result  }

 执行:

 

Java代码
  1. add 1 2 3  
  2. echo $?  
  3. echo $result  
add 1 2 3  echo $?  echo $result

两个输出结果都是:6.

这 里需要几点说明.shell中是不能直接获得函数的返回值的,如果你要用函数返回值,只能用全局变量传输。shell中的变量默认都是全局的,除非你在前 面加了local修饰符。如上面的例子,在函数外面,result变量也是可见的。如果你在result前加local修饰,result变量在函数外就 不可见了。但shell会把函数返回值放在$?全局变量中,你可以用$? 来取得前个函数调用的返回值。$*可以获得函数的所有输入参数,$1表示第一个参数,以此类推。

 

五.其他

shell内置的一些特征,可以很容易的处理文件,以及和其他程序交互。

Xml代码
  1. 文件比较运算符  
  2.   
  3. -e filename     如果 filename存在,则为真   [ -e /var/log/syslog ]  
  4. -d filename     如果 filename为目录,则为真  [ -d /tmp/mydir ]  
  5. -f filename     如果 filename为常规文件,则为真    [ -f /usr/bin/grep ]  
  6. -L filename     如果 filename为符号链接,则为真    [ -L /usr/bin/grep ]  
  7. -r filename     如果 filename可读,则为真   [ -r /var/log/syslog ]  
  8. -w filename     如果 filename可写,则为真   [ -w /var/mytmp.txt ]  
  9. -x filename     如果 filename可执行,则为真  [ -L /usr/bin/grep ]  
  10. filename1-nt filename2  如果 filename1比 filename2新,则为真    [ /tmp/install/etc/services -nt /etc/services ]  
  11. filename1-ot filename2  如果 filename1比 filename2旧,则为真    [ /boot/bzImage -ot arch/i386/boot/bzImage ]  
文件比较运算符    -e filename  如果 filename存在,则为真  [ -e /var/log/syslog ]  -d filename  如果 filename为目录,则为真  [ -d /tmp/mydir ]  -f filename  如果 filename为常规文件,则为真  [ -f /usr/bin/grep ]  -L filename  如果 filename为符号链接,则为真  [ -L /usr/bin/grep ]  -r filename  如果 filename可读,则为真  [ -r /var/log/syslog ]  -w filename  如果 filename可写,则为真  [ -w /var/mytmp.txt ]  -x filename  如果 filename可执行,则为真  [ -L /usr/bin/grep ]  filename1-nt filename2  如果 filename1比 filename2新,则为真  [ /tmp/install/etc/services -nt /etc/services ]  filename1-ot filename2  如果 filename1比 filename2旧,则为真  [ /boot/bzImage -ot arch/i386/boot/bzImage ]  
 

for 循环中很容易遍历文件

Js代码
  1. for file in /home/*  
  2. do  
  3.    if [ -d "$file" ]   
  4.    then  
  5.       echo $file is a directory  
  6.     fi  
  7. done  
for file in /home/*  do     if [ -d "$file" ]      then        echo $file is a directory      fi  done

很容易调用其他程序的输出结果:

 

Js代码
  1. for user in `awk -F":" '{ print $1 }' /etc/passwd`  
  2. do  
  3.     echo find user $user  
  4. done  
for user in `awk -F":" '{ print $1 }' /etc/passwd`  do      echo find user $user  done

 shell脚步中要使用其他命令的输出结果,只需用`符号把命令包含起来。注意:这个符号不是单引号,在键盘左上角那个位置。

 

六. 后记

基本的shell语法就学了这些,高级的还没弄通。这篇笔记也差不多长了,别的再边学边写。shell是基础,要配合awk,grep,sed这些工具才能发挥出效果。最近在看《unix编程艺术》,上面谈到了*nix系统的几个哲学基础原则,其中有个原则就是:

组合原则:设计时考虑拼接组合

*nix系统程序的的输入和输出一般都是简单,文本化,面向流的格式。这样便于程序和程序之间的交互和拼接。*nix系统下的程序一般都只完成单一功能,如果你需要要一个复杂的功能,那就需要把小程序拼接在一起。这一特征也决定了shell在*uix系统中的重要性。

 

七.shell学习资料

1.IBM Shell编程系列 

本文中的许多例子以及资料就是来自该系列教程

2.Bash 参考手册

Gnu的bash官方参考手册

  评论这张
 
阅读(711)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017