shell编程

第一个shell脚本

使用vim编辑first.sh

$ vim first.sh

编辑first.sh

clear
echo "Hello $USER"
echo "Today is \c ";date
echo "Number of user login : \c" ; who | wc -l
echo "Calendar"
cal
exit 0

执行时,需要

$ chmod 755 frist.sh
$ ./first.sh

或者是

$ sh first.sh

系统变量

系统变量名称 变量名的意义
BASH=/bin/bash shell名
BASH_VERSION=1.14.7(1) shell版本名
COLUMNS=80 屏幕中的第几列
HOME=/home/vivek home目录
LINES=25 屏幕中的第几列
LOGNAME=students 当前的登录名
OSTYPE=Linux 操作系统名
PATH=/usr/bin:/sbin:/bin:/usr/sbin PATH的设置
PS1=[\u@\h \W]\$ 提示设置
PWD=/home/students/Common 当前工作目录
SHELL=/bin/bash shell名
USERNAME=vivek 当前登录的用户名

使用echo命令查看环境变量,如

$ echo $HOME

变量的定义

定义的格式如下:

variable name=value

例如

$ no=10
$ echo $no

注意变量名是区分大小写的

no 与 No 不是一个变量

定义一个NULL变量, 可以如下

$ vech=
$ vech=""

介绍一下echo命令的选项

echo [options] [string, variables...]

其中options可以为

-n 不作为一行输出,即输出后不换行
-e 将下面的反斜杠解释成转义字符:
\a  警报
\b 删除
\c 不换行
\n 新建一行
\r 回车键
\t 水平tab
\\ 反斜杠

$ echo -e "An apple a day keeps away \a\t\tdoctor\n"

打印彩色字符串

$ echo -e "\033[34m   Hello Colorful  World!"

1) 第一个\033是换码符

2) 用[34m设置屏幕的前背景是蓝色

 

 character or letter

use in CSI 

 例子
 h  设置ANSI模式 echo -e "\033[h"  
 清除ANSI模式  echo -e "\033[l"
 设置输出字的颜色以及是否粗体  echo -e  "\033[35m Hello World"
 设置num lock,caps lock,scroll lock开还是关  echo -e "\033[2q"
 存储当前光标的x,y坐标还有属性  echo -e "\033[7s"
 重新存储当前光标的x,y坐标还有属性  echo -e "\033[8u"

 

其中m参数的意义如下

参数 意义  例子
0 设置默认的颜色模式  
1 设置粗体强度 $ echo -e "I am \033[1m BOLD \033[0m Person"
2 设置暗淡强度 $ echo -e "\033[1m  BOLD \033[2m DIM  \033[0m"
5 设置闪烁强度 $ echo -e "\033[5m Flash!  \033[0m"
7 设置相反的效果 $ echo -e "\033[7m Linux OS! Best OS!! \033[0m"
11

显示特殊控制字符图形字符。

对于如从按下Alt键和数字键盘按178发,

放开两个键;没有将被打印。

试一下示例中的输出

$ press alt + 178

$ echo -e "\033[11m"
$ press alt + 178
$ echo -e "\033[0m"
$ press alt + 178

25 删除闪烁效果  
27 删除相反效果  
30 - 37

设置前景颜色:

31 - 红色

32 - 绿色

xx - 自己试一下

 

 $ echo -e "\033[31m I am in Red"
40 - 47

设置背景颜色

xx - 自己试一下

 $ echo -e "\033[44m Wow!!!"

q参数的意义如下

参数 意义
0 关掉所有键盘的LED灯
1 Scroll lock LED 打开,其他的关掉
2 Num lock LED 打开,其他的关掉
3  Caps lock LED 打开,其他的关掉

算术运算

算术运算的格式如下:

expr op1 math-operator op2

示例:

$ expr 1 + 3
$ expr 2 - 1
$ expr 10 / 2
$ expr 20 % 3
$ expr 10 \* 3
$ echo `expr 6 + 3`

注意乘法使用 \* 而不是 *

注意最后一个示例不是单引号,是ESC键下面的键的符号

用双引号或单引号只是打印字符串, 如下

$ echo "expr 6 + 3" 
$ echo 'expr 6 + 3' 

双引号: 在双引号里面的内容会将特殊字符替换

单引号: 在单引号里面的内容不会变,直接打印

反引号(即ESC键下面的键):里面的内容作为命令执行之后替换

如下:

$ echo "Today is date"
$ echo 'Today is date'
$ echo "Today is `date`"
$ echo 'Today is `date`'

命令退出状态

1) 如果返回值是0, 则说明命令执行成功

2) 如果返回值不是0, 则说明命令没有执行成功,或者是脚本中一些命令没有执行成功

使用 $?
用echo $?查看上一条命令的执行状态

$ ls
$ echo $?

读取变量

读取变量名的格式如下:

read variable1, variable2,...variableN

编辑sayH文件

echo "Your first name please:"
read fname
echo "Hello $fname, Lets be friend!"

下面执行

$ chmod 755 sayH
$ ./sayH

如果一行使用多个命令,命令之间使用;隔开

$ date;who 

如果一个脚本有参数,在脚本内 $0 是脚本名,$1 是第一个参数, $2 是第二个参数,$# 是传递的参数个数, $@ 或 $* 是所有的参数

编辑demo文件

#!/bin/sh
#
# Script that demos, command line args
#
echo "Total number of command line argument are $#"
echo "$0 is script name"
echo "$1 is first argument"
echo "$2 is second argument"
echo "All of them are :- $* or $@"

执行

$ chmod 755 demo
$ ./demo Hello World

管道

使用格式如下
command1 | command2

$ who | wc -l

第一条命令的输出结果作为第二条命令的输入

 bc是计算命令

$bc
5 + 2 
5 > 12
5 == 10
5 != 2
5 == 5
12 < 2
表达式 含义 答案 bc的结果
5 > 12 5是否大于12 NO 0
5 == 10 5是否等于10 NO 0
5 != 2 5是否不等于2 YES 1
5 == 5 5是否等于5 YES 1
12 < 2 12是否小雨2 NO 0

if条件语句

使用格式如下

if condition
then
command1 if condition is true or if exit status
of condition is 0 (zero)
...
...
fi

编辑showfile文件

#!/bin/sh
#
#Script to print file
#
if cat $1
then
echo -e "\n\nFile $1, found and successfully echoed"
fi

执行

$ chmod 755 showfile
$./showfile foo

编辑ispostive文件

#!/bin/sh
#
# Script to see whether argument is positive
#
if test $1 -gt 0
then
echo "$1 number is positive"
fi

执行

$ chmod 755 ispostive
$ ispostive 5

判断条件 

test 或者 [expr] 作用于整数,文件类型,字符串

数学符号 含义 一般表达式 shell中的test shell中的[expr]
-eq 等于 5 == 6 if test 5 -eq 6 if [ 5 -eq 6 ]
-ne 不等于 5 != 6 if test 5 -nq  6 if [ 5 -nq  6 ]
-lt 小于 5 < 6 it test 5 -lt 6 if [ 5 -lt 6 ]
-le 小于或等于 5 <= 6 if test 5 -le 6 if [ 6 -le 6 ]
-gt 大于 5 > 6 it test 5 -gt 6  if [5 -gt 6 ]
-ge 大于或等于 5 >= 6 if test 5 -ge 6 if [ 5 -ge 6]

对字符串的比较

操作符 含义
string1 = string2

string1 是否等于string2

string1 != string2 string1 是否不等于 string2
string1 string1 不为 NULL 或 不是没定义
-n string1 string1 不为NULL 并且存在
-z string1  string1 为NULL 并且存在

对于文件或者是目录

test 含义
-s file 不为空文件
-f file 文件是否存在或是普通文件并且不是目录
-d dir 目录是否存在且不是一个普通文件
-w file 文件是否可写
-r file 文件是否可读
-x file 文件是否可执行

逻辑运算

运算符 含义
! expression 逻辑非
expression1 -a expression2 逻辑与
expression1 -o expression2 逻辑或

条件语句 if - else - fi 

使用格式如下

if condition
then
  condition is zero (true - 0)
  execute all commands up to else statement

else
  if condition is not true then
  execute all commands up to fi
fi

编辑isnump_n文件

#!/bin/sh
#
# Script to see whether argument is positive or negative
#
if [ $# -eq 0 ]
then
echo "$0 : You must give/supply one integers"
exit 1
fi

if test $1 -gt 0
then
echo "$1 number is positive"
else
echo "$1 number is negative"
fi

执行

$ chmod 755 isnump_n
$ isnump_n 5
$ isnump_n -45 
$ isnump_n
$ isnump_n 0

嵌套if - else - fi

使用格式如下

	if condition
	then
		if condition
		then
			.....
			..
			do this
		else
			....
			..
			do this
		fi
	else
		...
		.....
		do this
	fi

编辑nestedif.sh

osch=0

echo "1. Unix (Sun Os)"
echo "2. Linux (Red Hat)"
echo -n "Select your os choice [1 or 2]? "
read osch

if [ $osch -eq 1 ] ; then

     echo "You Pick up Unix (Sun Os)"

else #### nested if i.e. if within if ######
            
       if [ $osch -eq 2 ] ; then
             echo "You Pick up Linux (Red Hat)"
       else
             echo "What you don't like Unix/Linux OS."
       fi
fi

执行

$ chmod +x nestedif.sh
$ ./nestedif.sh
$ ./nestedif.sh
$ ./nestedif.sh

多层if - else - fi

if condition
then
  condition is zero (true - 0)
  execute all commands up to elif statement
elif condition1
then
  condition1 is zero (true - 0)
  execute all commands up to elif statement
elif condition2
then
  condition2 is zero (true - 0)
  execute all commands up to elif statement
else
  None of the above condtion,condtion1,condtion2 are true (i.e.
  all of the above nonzero or false)
  execute all commands up to fi
fi

编辑elf

#
#!/bin/sh
# Script to test if..elif...else
#
if [ $1 -gt 0 ]; then
  echo "$1 is positive"
elif [ $1 -lt 0 ]
then
  echo "$1 is negative"
elif [ $1 -eq 0 ]
then
  echo "$1 is zero"
else
  echo "Opps! $1 is not number, give number"
fi

执行

$ chmod 755 elf
$ ./elf 1
$ ./elf -2
$ ./elf 0
$ ./elf a

shell中的循环

for 循环

格式如下:

for { variable name } in { list }
do
  execute one for each item in the list until the list is
  not finished (And repeat all statement between do and done)
done

编辑testfor文件

for i in 1 2 3 4 5
do
echo "Welcome $i times"
done

执行

$ chmod +x testfor
$ ./testfor

编辑mtable文件

#!/bin/sh
#
#Script to test for loop
#
#
if [ $# -eq 0 ]
then
echo "Error - Number missing form command line argument"
echo "Syntax : $0 number"
echo "Use to print multiplication table for given number"
exit 1
fi
n=$1
for i in 1 2 3 4 5 6 7 8 9 10
do
echo "$n * $i = `expr $i \* $n`"
done

执行

$ chmod 755 mtable
$ ./mtable 7
$ ./mtable

另一种格式如下

for (( expr1; expr2; expr3 ))
do
  .....
  ...
  repeat all statements between do and
  done until expr2 is TRUE
Done

编辑for2文件

for ((  i = 0 ;  i <= 5;  i++  ))
do
  echo "Welcome $i times"
done

执行

$ chmod +x for2
$ ./for2

嵌套for循环

编辑nestedfor文件

for (( i = 1; i <= 5; i++ ))      ### Outer for loop ###
do

    for (( j = 1 ; j <= 5; j++ )) ### Inner for loop ###
    do
          echo -n "$i "
    done

  echo "" #### print the new line ###

done

执行

$ chmod +x nestedfor.sh
$ ./nestefor.sh

编辑chessboard文件

for (( i = 1; i <= 9; i++ )) ### Outer for loop ###
do
   for (( j = 1 ; j <= 9; j++ )) ### Inner for loop ###
   do
        tot=`expr $i + $j`
        tmp=`expr $tot % 2`
        if [ $tmp -eq 0 ]; then
            echo -e -n "\033[47m "
        else
            echo -e -n "\033[40m "
        fi
  done
 echo -e -n "\033[40m" #### set back background colour to black
 echo "" #### print the new line ###
done

执行

$ chmod +x chessboard $ ./chessboard

while循环

使用格式如下

while [ condition ]
do
  command1
  command2
  command3
  ..
  ....
done

编辑nt1文件

#!/bin/sh
#
#Script to test while statement
#
#
if [ $# -eq 0 ]
then
   echo "Error - Number missing form command line argument"
   echo "Syntax : $0 number"
   echo " Use to print multiplication table for given number"
exit 1
fi
n=$1
i=1
while [ $i -le 10 ]
do
  echo "$n * $i = `expr $i \* $n`"
  i=`expr $i + 1`
done

执行

$ chmod 755 nt1
$./nt1 7

case语句

使用格式如下

case $variable-name in
pattern1) command
  ...
  ..
  command;;
pattern2) command
  ...
  ..
  command;;
patternN) command
  ...
  ..
  command;;
*) command
  ...
  ..
  command;;
esac

编辑car文件

#
# if no vehicle name is given
# i.e. -z $1 is defined and it is NULL
#
# if no command line arg
if [ -z $1 ]
then
  rental="*** Unknown vehicle ***"
elif [ -n $1 ]
then
# otherwise make first arg as rental
  rental=$1
fi

case $rental in
   "car") echo "For $rental Rs.20 per k/m";;
   "van") echo "For $rental Rs.10 per k/m";;
   "jeep") echo "For $rental Rs.5 per k/m";;
   "bicycle") echo "For $rental 20 paisa per k/m";;
   *) echo "Sorry, I can not gat a $rental for you";;
esac

执行

$ chmod +x car
$ car van
$ car car
$ car Maruti-800

如何de-bug shell脚本

使用格式

sh options {shell 脚本名}

或者是

bash options {shell 脚本名}

options可以是

-v 当shell读脚本时把脚本内容打印出来

-x 脚本中的命令会展开打印出来

编辑dsh1文件

#
# Script to show debug of shell
#
tot=`expr $1 + $2`
echo $tot

执行

$ chmod 755 dsh1.sh
$ ./dsh1.sh 4 5
$ sh -x dsh1.sh 4 5
$ sh -v dsh1.sh 4 5

第一个输出结果

9

第二个输出结果

+ expr 4 + 5
+ tot=9
+ echo 9
9

第三个输出结果

#
#script to show debug of shell
#
tot=`expr $1 + $2`
echo $tot
9

更好的学习资料

 

posted @ 2016-05-05 09:48  海上的风  阅读(200)  评论(0编辑  收藏  举报