shell细节语法

1-脚本名称叫test.sh 入参三个: 1 2 3

运行test.sh 1 2 3后
$*为"1 2 3"(一起被引号包住)
$@为"1" "2" "3"(分别被包住)
$#为3(参数数量)

 case语句格式
# vi test.sh
:
echo "input : "
read num
echo "the input data is $num"

case $num in
1) echo "January";;     双分号结束
2) echo "Feburary";;
5) echo "may"          每个case可以有多条命令       
   echo "sdfd"
   echo "sdf";;        但最后一条命令一定是双分号结束

*) echo "not correct input";;   *)是其他值、default的意思      

esac    
# sh ./test.sh
input :
2
the input data is 2
Feburary

# sh ./test.sh
input :
ter
the input data is ter
not correct input   

 
    case 语句如果某个选项没有任何语句,也要加;; 否则会出下边错误
test: line 166: syntax error near unexpected token `)'
test: line 166: `"system hostname config")'


    为什么输入no,仍不匹配到[no]
原来[]是专门针对单字符的值,如果用[no],就是n和o之一
case $yn in  
 [no]) return 1;;
  * )  echo "only accept Y,y,N,n,YES,yes,NO,no" >&2;;
[macg@mac-home ~]$ sh test.sh
enter y/n :
no                           
only accept Y,y,N,n,YES,yes,NO,no
改正
case $yn in  
  no) return 1;;
  NO) return 1;;
  * ) echo "only accept Y,y,N,n,YES,yes,NO,no" >&2;;
 esac
[macg@mac-home ~]$ sh test.sh
enter y/n :
no                            


    一个getyn()函数的例子
getyn( )
{
while echo "enter y/n :"
do
 read yn
 case $yn in
  [Yy]) return 0 ;;
  yes) return 0 ;;
  YES) return 0 ;;
  [Nn]) return 1 ;;
  no) return 1;;
  NO) return 1;;
  * ) echo "only accept Y,y,N,n,YES,yes,NO,no" ;;
 esac
done
}
if
getyn  调用函数      以函数作为if条件,必须用if command法
then     注意0为真
echo " your answer is yes"
else
echo "your anser is no"
fi   


    if,  case,匹配字符串最常见,但如何匹配一段很长的输出,一堆文字?最好方法,用“*”,如:*"command not found"*
[macg@machome ~]$ vi test.sh

var=$(ls -l $1)      $()取命令输出$1是命令行参数
echo "output is $var"

case $var in
"-rw-rw-r--"*) echo "this is not a execute file";;
"-rwxrwxr-x"*) echo "this is a execute file";
注意*在双引号外边
esac
[macg@machome ~]$ sh test.sh 22.txt
output is -rw-rw-r--  1 macg macg 15 Jun  9 19:00 22.txt
this is not a execute file

[macg@machome ~]$ chmod +x 22.txt
[macg@machome ~]$ sh test.sh 22.txt
output is -rwxrwxr-x  1 macg macg 15 Jun  9 19:00 22.txt
this is a execute file
    例2.匹配file命令输出的一堆文字,以获知文件类型
用’ ’ 取输出,然后用CASE+*对输出做修饰处理.
[macg@machome ~]$ vi test.sh

var=`file $1`        `  `和$( )作用相同,是取命令输出
echo "output is $var"

case $var in
"$1: ASCII text"*) echo "this is a text file";;
"$1: directory"*) echo "this is a directory";;
注意*在双引号外边
esac    
[macg@machome ~]$ sh test.sh 22.txt
output is 22.txt: ASCII text
this is a text file

[macg@machome ~]$ sh test.sh test-dir
output is test-dir: directory
this is a directory


      最典型的shell case命令匹配命令行,用于sys v启动脚本的start|stop|restart|status处理
  case   "$@"   in    
($@ 字符串数组:以"参数1" "参数2" ... 的字符串数组形式保存所有参数 
对于单个参数的情况,$@就是一个字符串)

  start)    
          echo   -n   "Starting   firewall..."    
          。。。  
          echo   "OK!"    
          exit   0    
          ;;    
  stop)    
          echo   -n   "Stopping   firewall..."
          。。。   
          exit   0    
          ;;   
restart   
          $0   stop     $0即执行原始程序       
          $0   start    
          ;;    
status)    
          clear    
          echo   ">------------------------------------------"    
          iptables   -L    
          echo   ">------------------------------------------"    
          iptables   -t   nat   -L   POSTROUTING    
          exit   0   
     *)    
          echo   "Usage:   $0   {start|stop|restart|status}"    
          exit   1    
  esac  

http://blog.sina.com.cn/s/blog_6151984a0100ekq0.html
 1 #!/bin/bash
 2 
 3 echo $#
 4 echo $@
 5 echo $*
 6 func ()
 7 {
 8     echo "hello world"
 9 }
10 echo "input : "
11 read num
12 echo "the input data is $num"
13 
14 case $num in 
15 1) echo "January";;    # 双分号结束
16 2) echo "Feburary";;
17 5) echo "may"          #每个case可以有多条命令        
18    echo "sdfd"
19    echo "sdf";;        #但最后一条命令一定是双分号结束
20 6) "func";;
21 
22 *) echo "not correct input";;   #*)是其他值、default的意思      
23 
24 esac   

linux shell 可以用户定义函数,然后在shell脚本中可以随便调用。下面说说它的定义方法,以及调用需要注意那些事项。

 

一、定义shell函数(define function)

语法:

[ function ] funname [()]

{

    action;

    [return int;]

}

说明:

1、可以带function fun()  定义,也可以直接fun() 定义,不带任何参数。

2、参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0-255

 

实例(testfun1.sh):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!/bin/sh
  
 fSum 3 2;
 function fSum()
 {
     echo $1,$2;
     return $(($1+$2));
 }
 fSum 5 7;
 total=$(fSum 3 2);
 echo $total,$?;
                  
sh testfun1.sh
testfun1.sh: line 3: fSum: command not found
5,7
3,2
1
5

 

从上面这个例子我们可以得到几点结论:

1、必须在调用函数地方之前,声明函数,shell脚本是逐行运行。不会像其它语言一样先预编译。一次必须在使用函数前先声明函数。

2、total=$(fSum 3 2);  通过这种调用方法,我们清楚知道,在shell 中 单括号里面,可以是:命令语句。 因此,我们可以将shell中函数,看作是定义一个新的命令,它是命令,因此 各个输入参数直接用 空格分隔。 一次,命令里面获得参数方法可以通过:$0…$n得到。 $0代表函数本身。

3、函数返回值,只能通过$? 系统变量获得,直接通过=,获得是空值。其实,我们按照上面一条理解,知道函数是一个命令,在shell获得命令返回值,都需要通过$?获得。

 

二、函数作用域,变量作用范围

先我们看一个实例(testfun2.sh ):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#!/bin/sh
 
echo $(uname);
declare num=1000;
 
uname()
{
    echo "test!";
    ((num++));
    return 100;
}
testvar()
{
    local num=10;
    ((num++));
    echo $num;
 
}
 
uname;
echo $?
echo $num;
testvar;
echo $num;
                
                               
sh testfun2.sh
Linux
test!
100
1001
11
1001

我们一起来分析下上面这个实例,可以得到如下结论:

1、定义函数可以与系统命令相同,说明shell搜索命令时候,首先会在当前的shell文件定义好的地方查找,找到直接执行。

2、需要获得函数值:通过$?获得

3、如果需要传出其它类型函数值,可以在函数调用之前,定义变量(这个就是全局变量)。在函数内部就可以直接修改,然后在执行函数就可以读出修改过的值。

4、如果需要定义自己变量,可以在函数中定义:local 变量=值 ,这时变量就是内部变量,它的修改,不会影响函数外部相同变量的值 。

这些,是我在工作中,对linux ,shell 函数使用一些经验总结,有没有提到地方,欢迎交流!

 

 

SHELL学习笔记----IF条件判断,判断条件

前言:

      无论什么编程语言都离不开条件判断。SHELL也不例外。

      if list then 
          do something here 
      elif list then 
          do another thing here 
      else 
         do something else here 
      fi 
   

EX1:

#!/bin/sh

SYSTEM=`uname -s`    #获取操作系统类型,我本地是linux

if [ $SYSTEM = "Linux" ] ; then     #如果是linux的话打印linux字符串
echo "Linux" 
elif [ $SYSTEM = "FreeBSD" ] ; then   
echo "FreeBSD" 
elif [ $SYSTEM = "Solaris" ] ; then 
echo "Solaris" 
else 
echo "What?" 
fi     #ifend

基本上和其他脚本语言一样。没有太大区别。不过值得注意的是。[]里面的条件判断。

1 字符串判断

str1 = str2      当两个串有相同内容、长度时为真 
str1 != str2      当串str1和str2不等时为真 
-n str1        当串的长度大于0时为真(串非空) 
-z str1        当串的长度为0时为真(空串) 
str1           当串str1为非空时为真

2 数字的判断

int1 -eq int2    两数相等为真 
int1 -ne int2    两数不等为真 
int1 -gt int2    int1大于int2为真 
int1 -ge int2    int1大于等于int2为真 
int1 -lt int2    int1小于int2为真 
int1 -le int2    int1小于等于int2为真

3 文件的判断

-r file     用户可读为真 
-w file     用户可写为真 
-x file     用户可执行为真 
-f file     文件为正规文件为真 
-d file     文件为目录为真 
-c file     文件为字符特殊文件为真 
-b file     文件为块特殊文件为真 
-s file     文件大小非0时为真 
-t file     当文件描述符(默认为1)指定的设备为终端时为真

3 复杂逻辑判断

-a         与 
-o        或 
!        非

结尾

    语法虽然简单,但是在SHELL里使用的时候,他的功能变得强大了。

posted @ 2013-05-27 15:12  GOD_YCA  阅读(1518)  评论(0)    收藏  举报