Linux程序设计学习系列(第二章)

第二章 shell程序设计

创建脚本示例

脚本内容

#!/bin/sh
#first
#it's am example for perfectxhj
for file in *
do 
  if grep -q POSIX $file
  then 
      echo $file
  fi
done

exit 0

其中,exit返回的是一个退出码,当此脚本被其他脚本调用时,退出码就可以被返回以查看。0表示成功。

设定为可执行

/bin/sh first
使用: chmod +x first 可以让所有用户都能执行这个文件。(让程序变为可执行文件)
./first 亦可以运行该程序,同时可以将脚本的完整相对路径告诉shell。

2.6 shell的语法

变量

在shell中,可以通过在变量名前加上$符号来访问它的内容。而为变量赋值时,只需使用变量名就可以被自动创建。
如:

test=Hello
echo $test

输出: Hello
注:如果字符串中包含空格,就要把他们用括号括起来。同时等号两边不能有空格。
read命令可以接收用户要输入的数据,按下回车键,则read命令结束。如下所示:

root@xhj-2:/usr/linuxProgramming# read what
perfectxhj
root@xhj-2:/usr/linuxProgramming# echo $what
perfectxhj
1.引号的使用

在脚本文件中,一个变量如果放在双引号里,程序执行时会自动替换其为它的值,如果在单引号里面,就不会发生替换。同时,在$变量前面加上\可以取消其特殊含义。

root@xhj-2:/usr/linuxProgramming# cat myvar 
!/bin/sh 
myvar="Hi there"
echo $myvar
echo "$myvar"
echo '$myvar'
echo \$myvar

echo Enter some text
read myvar

echo '$myvar' now equals $myvar
exit 0

结果展示:

Hi there
Hi there
$myvar
$myvar
Enter some text
xixi
$myvar now equals xixi
2.环境变量

当一个shell脚本开始执行时,一些变量会根据环境设置中的值进行初始化。具体如下图所示:
在这里插入图片描述

实验:使用参数和环境变量
root@xhj-2:/usr/linuxProgramming# cat try_var 
#!/bin/sh
salutation="Hello"
echo $salutation
echo "The program $0 is now running"
echo "The second parameter was $2"
echo "The first parameter was $1"
echo "The parameter list was $*"
echo "The user's home directorory is $HOME"

echo "Please enter a new greeting"
read salutation

echo $salutation
echo "The script is now complete"
exit 0

输出如下所示:

root@xhj-2:/usr/linuxProgramming# ./try_var foo bar baz
Hello
The program ./try_var is now running
The second parameter was bar
The first parameter was foo
The parameter list was foo bar baz
The user's home directorory is /root
Please enter a new greeting
Sire
Sire
The script is now complete

这个实验创建变量并显示其内容,同时还显示了各种参数变量以及环境变量等。

实验:测试/bin/bash文件状态
root@xhj-2:/usr/linuxProgramming# cat filestatus 
#!/bin/sh

if [ -f /bin/bash ]
then
  echo "file /bin/bash exists"
fi

if [ -d /bin/bash ]
  echo "/bin/bash is a directory"
else
  echo "/bin/bash is not a directory"
fi
root@xhj-2:/usr/linuxProgramming# vim filestatus 
root@xhj-2:/usr/linuxProgramming# ./filestatus 
file /bin/bash exists
/bin/bash is not a directory
2.6.3 控制结构

if语句结构:
if condition
then
statements
else
statements
fi

实验:使用if语句
root@xhj-2:/usr/linuxProgramming# cat timeofday 
#!/bin/sh

echo "Is it morning?Please answer yes or no"
read timeofday

if [ $timeofday = "yes" ]; then
  echo "Good morning"
else 
  echo "Good afternoon"
fi

exit 0
实验:使用复杂if语句
root@xhj-2:/usr/linuxProgramming# cat timeofday 
#!/bin/sh

echo "Is it morning?Please answer yes or no"
read timeofday

if [ $timeofday = "yes" ]; then
  echo "Good morning"
elif [ $timeofday = "no" ]; then 
  echo "Good afternoon"
else 
  echo "U r wrong"
fi

exit 0

也就是说,在shell脚本中,所使用的的if语句结构为:
if语句结构:
if condition
then
statements
elif
statements
then
statements
else
statements
fi

for语句结构

for cvariable in values
do
statements
done

实验:使用for循环
root@xhj-2:/usr/linuxProgramming# cat forexample 
#!/bin/sh

for foo in bar foos fud 4546
 do
    echo $foo
done

exit 0

实验:使用通配符拓展的for循环

本实验作用是用shell拓展把*拓展为当前目录中所有文件的名字,然后依次作为for循环中的变量$使用。

root@xhj-2:/usr/linuxProgramming# cat forex
#!/bin/sh

for file in $(ls h*.c)
 do
   echo $file
done 
exit 0
while语句结构

for循环社适合于已知循环次数的情况,因为所有shell变量值都被认为是字符串,所以for循环特别适合于一些列字符串进行循环处理。但当实现不知道循环的次数,这时候就要用while循环了。
while condition do
statements
done

实验:密码检查程序
root@xhj-2:/usr/linuxProgramming# cat pwdchk 
#!/bin/sh

echo "Enter your password"
read password

while [ "$password" != "secret" ]
do 
   echo "Sorry,try again"
   read password
done
exit 0

until语句结构

until语句跟while循环很相似,只是把条件测试反过来了,循环将反复执行直到条件为真,在条件为真时反复执行。
until语句的语法如下所示:(感觉有点像 do ……while……)
until condition
do
statements
done

实验:设定警报,当特定用户登录时,警报启动。
#!/bin/bash

until who | grep "$1" > /dev/null
do
 sleep 60
done

# now ring the bell and announce the expected user

echo -e '\a'
echo "*********$1 has just logged in"
exit 0

case结构

注:case中每个模式行都需要双分号来结尾。
case variable in
pattern [ | pattern ] …) statements;;
pattern [ | pattern ] …) statements;;

esac

实验:case1 用户输入
root@xhj-2:/usr/linuxProgramming# cat case1
#!/bin/bash

echo "Is it morning? Please answer yes or no"
read time

case "$time" in
 yes) echo "Morning";;
 no) echo "afternoon";;
 *) echo "wrong";;
esac

exit 0

实验:case2 合并匹配模式
root@xhj-2:/usr/linuxProgramming# cat case2
#!/bin/bash

echo "Is it morning?Please answer yes or no"
read time

case "$time" in
  yes | y | Yes |YES) echo "morning";;
   n* | N* ) echo "afternoon";;
 *) echo "wrong";;

esac

exit 0
实验:case3 执行多条语句
root@xhj-2:/usr/linuxProgramming# cat case3
#!/bin/bash

echo "Is it morning?"
read time

case "$time" in
  yes | y |Yes |YES )
      echo "morning!"
      echo "Up bright and early this morning"
      ;;
   [nN]*)
      echo "Good afternoon"
      ;;
   *)
      echo "wrong"
      echo "Please answer yes or no"
      exit 1
      ;;
esac

exit 0
实验:AND列表

and列表也就是用一些列的&&符号来连接多个语句,只有这些语句都为真,整体的and列表才为真。同时只有前一个语句为真下一个被&&所连接的语句才会执行

root@xhj-2:/usr/linuxProgramming# cat and
#!/bin/bash

touch file_one
rm -f file_two

if [ -f file_one ] && echo "Hello" && [ -f file_two ] && echo "there"
then 
 echo "in if"
else 
 echo "in else"
fi

exit 0

输出:
Hello
in else

实验:OR列表

or列表允许我们持续执行一系列命令一直到有一条命令成功为止,成功后这条命令之后的命令将不再执行。

root@xhj-2:/usr/linuxProgramming# cat and
#!/bin/bash

rm -f file_one

if [ -f file_one ] || echo "Hello" || echo "there"
then 
 echo "in if"
else 
 echo "in else"
fi

exit 0

输出:
Hello
in if

函数
实验:一个简单的函数
root@xhj-2:/usr/linuxProgramming# cat function 
#!/bin/bash

foo(){
echo "Function foo is executing"
}
echo "script starting"
foo
echo "script ended"
exit 0

输出:
script starting
Function foo is executing
script ended
注意:在调用一个函数之前,要先对其进行定义。shell脚本是从顶部开始执行的。
通过return可以返回数字值,字符值的返回可以利用变量来保存,该变量可以在函数结束之后被使用。同时也可以echo一个字符串并捕获其结果。

foo(){echo JAY;}
……
result="$(foo)"

注意:local关键字可以在shell函数中声明局部变量,该变量只在该函数中有效。若局部变量和全局变量同名,在该函数内部局部变量覆盖全局变量。

实验:变量作用域
root@xhj-2:/usr/linuxProgramming# cat variable 
#!/bin/bash

sample_text="global variable"
foo(){
local sample_text="local variable"
echo "Function foo is executing"
echo $sample_text
}
echo "script starting"
echo $sample_text
foo
echo "script ended"
echo $sample_text

exit 0

输出:
script starting
global variable
Function foo is executing
local variable
script ended
global variable

实验:函数返回一个值
root@xhj-2:/usr/linuxProgramming# cat return
#!/bin/bash

yes_or_no(){
 echo "Is your name $* ?"
while true
do
  echo -n "Enter yes or no:"
  read x
  case "$x" in
    y|yes) return 0;;
    n|no ) return 1;;
    *) echo "Answer yes or no"
  esac
done
}

echo "Original parameters are $*"
if yes_or_no "$1"
then
 echo "Hi $1,nice name"
else
 echo "Never mind"
fi
exit 0

输出:

root@xhj-2:/usr/linuxProgramming# ./return hh hhh
Original parameters are hh hhh
Is your name hh ?
Enter yes or no:y
Hi hh,nice name

在这个程序中,首先定义了一个函数,但并不会立即执行。当执行到if时,首先把$1替换为脚本程序的第一个参数hh,再把它作为参数传递给这个函数。函数将使用这些参数并向调用者返回一个值。

break命令

break默认情况下跳出一层循环

root@xhj-2:/usr/linuxProgramming# cat break
#!/bin/bash

rm -rf fred*

echo > fred1
echo > fred2
mkdir fred3
echo > fred4

for file in fred*
do
 if [ -d "$file" ]; then
   break;
 fi
done

echo " first dir starting fred was $file"
rm -rf fred*
exit 0

输出:
first dir starting fred was fred3

:命令

冒号是一个空命令,相当于true的别名,常用在
1.while循环的条件,如while:实现了一个无线循环,代替的是while true
2.用在变量的条件设置中,如:

${var:=true}

示例:

root@xhj-2:/usr/linuxProgramming# cat maohao
#!/bin/bash

rm -f fred
if [ -f fred ]; then
:
else
echo file fred did not exist
fi

exit 0

输出:
file fred did not exist

:continue命令

该命令使for、while或者until循环跳到下一次循环继续执行,循环变量取循环列表中的下一个值。

root@xhj-2:/usr/linuxProgramming# cat continue 
#!/bin/bash

rm -rf fred*
echo > fred1
echo > fred2
mkdir fred3
echo > fred4
for file in fred*
do
  if [ -d "$file" ]; then
    echo "skipping dir $file"
  continue
fi
echo file is $file
done

rm -rf fred*

exit 0

输出:

root@xhj-2:/usr/linuxProgramming# ./continue
file is fred1
file is fred2
skipping dir fred3
file is fred4

.命令

用来在当前shell中执行命令。
作用类似于C语言中的#include指令。

eval命令

用来对参数求值。

foo=10
x=foo
y='$'$x
echo $y

输出$foo

foo=10
x=foo
eval y='$'$x
echo $y

输出10

export命令

将作为它参数的变量导出到子shell中,并使之在子shell中有效。

expr命令

将它的参数当做一个表达式来求值。

set命令

为shell设置参数变量。

grep命令

grep代表的是通用正则表达式解析器。
grep命令使用一个选项、一个要匹配的模式和要搜索的文件,语法:
grep [options] PATTERN [FILES]
在这里插入图片描述

2.6.6命令的执行

1.算术拓展

将准备求值的表达式括在$((……))中能有效完成简单的算术运算。

root@xhj-2:/usr/linuxProgramming# cat suanshu 
#!/bin/bash
x=0
while [ "$x" -ne 10 ];do
echo $x
x=$(($x+1))
done 
exit 0

输出是:
0
1
2
3
4
5
6
7
8
9
注:
-eq:等于
-ne:不等于
-le:小于等于
-ge:大于等于
-lt:小于
-gt:大于

2.参数拓展

在这里插入图片描述

root@xhj-2:/usr/linuxProgramming# cat canshu
#!/bin/bash

unset foo
echo ${foo:-bar}

foo=fud
echo ${foo:-bar}

foo=/usr/bin/X11/startx
echo ${foo#*/}
echo ${foo##*/}
bar=/usr/local/etc/local/networks
echo ${bar%local*}
echo ${bar%%local*}
exit 0

输出:

bar
fud
usr/bin/X11/startx
startx
/usr/local/etc/
/usr/

注:unset是从shell中删除对应的变量

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值