Linux Shell基本编程(下)

1. 结构化命令

(1)if-then语句

if command

then

commands

fi

示例:

 

#!/bin/bash
#testing multiple commands in the then section
testuser=root
if grep $testuser /etc/passwd
then
 echo the bash files for user $testuser are:
 ls -a /root/.b*
fi

 

grep是一个文本匹配命令。

 

(2)嵌套if语句

if command1

then

commands

elif command2

then

more commands

fi

 

示例:

#!/bin/bash
#testing the else section
testuser=badtest
if grep $testuser /etc/passwd
then
 echo the files for user $testuser are:
 ls -a /home/$testuser/.b*
else
 echo "the user name $testuser doesn't exist on the system"
fi

 

(3)test命令

有两种形式:

if test condition

then

commands

fi

与:

if [ condition ]

then

commands

fi

 

test命令主要是提供一种检测if-then语句中不同条件的方法。如果test评估条件为true,那么test命令以状态码0退出。

 

数值比较:

 

n1 -eq n2 检查n1是否等于n2

n1 -ge n2 检查n1是否大于等于n2

n1 -gt n2 检查n1是否大于n2

n1 -le n2 检查n1是否小于等于n2

n1 -lt n2 检查n1是否小于n2

n1 -ne n2 检查n1是否等于n2

 

示例:

#!/bin/bash
#using numeric test comparsions
var11=10
var12=11
if [ $var11 -gt 5 ]
then
 echo "the test value $var11 is greater than 5"
fi
if [ $var11 -eq $var12 ]
then
 echo "the values are equal"
else
echo "the values are different"
fi

 

 

字符串比较:

str1=str2  检查str1与str2是否相同

str1!=str2  检查str1与str2是否不同

str1<str2 检查str1是否小于str2

str1>str2  检查str1是否大于str2

-n  str1 检查str1的长度是否大于0

-z  str1 检查str1的长度是否为0

 

当比较一个字符串是大还是小时,一定要用转义字符进行转义,要不就当成重定向了。

 

示例:

 

#!/bin/bash
#>号会理解成重定向,因此需要转义
var11=aeball
var12=hockey
if [ $var11/>$var12 ]
then
echo "$var11 is greater than $var12"
else
echo "$var11 is less than $var12"
fi

 

 

 

#!/bin/bash
va11=testing
va12=''
if [ -n $vall ]
then
echo "the string '$va11' is not empty"
else
echo "the string '$va11' is empty"
fi
if [ -z $va12 ]
then
echo "the string '$va12' is empty"
else
echo "the string '$va12'is not empty"
fi
if [ -z $va13 ]
then
echo "the string '$va13' is empty"
else
echo "the string $va13 is not empty"
fi
~                  

 

文件比较:

-d file 检查file是否存在并且是一个目录

-e file 检查file是否存在

-f file 检查file是否存在并且是一个文件

-r file 检查file是否存在并且可读

-s file 检查file是否存在并且不为空

-w file 检查file是否存在并且可写

-x file 检查file是否存在并且可执行

-O file 检查file是否存在并且被当前用户拥有

-G file 检查file是否存在并且默认组是否为当前用户组

file1 -nt file2  检查file1是否比file2新

file1 -ot file2  检查file1是否比file2旧

 

 

示例:

检查目录:

#!/bin/bash
#look before you leap
if [ -d $HOME ]
then
echo "your home directory exists"
cd $HOME
ls -a
else
echo "there's a problem with your HOME directory"
fi

 

检查对象是否存在:

#!/bin/bash
#checking if a directory exists
if [ -e $HOME ]
then
 echo "OK on the directory,now let's check the file"
if  [ -e $HOME/testing ]
then
 echo "Appending data to existing file"
 date>>$HOME/testing
else
 echo "creating new file"
 date >$HOME/testing
fi
else
 echo "sorry,you don't have a home directory"
fi

检查文件:

#!/bin/bash
#check if a file
if [ -e $HOME ]
then
 echo "the object exists,is it a file?"
if [ -f  $HOME ]
then
echo "yes it's a file"
else
echo "no it's not a file"
if [ -f $HOME/.bash_profile ]
then
echo "but this is a file"
fi
fi
else
 echo "sorry the object doesn't exist"
fi

 

检查是否可读:

#!/bin/bash
#testing if you can read a file
pwfile=/etc/shadow
if [ -f $pwfile ]
then
 if [ -r $pwfile ]
 then
tail $pwfile
else
echo "sorry,the ‘'$pwfile' can't read"
fi
else
echo "sorry,the $file doesn't exist"
fi

 

检查文件是否为空:

#!/bin/bash
#testing if a file is empty
file=test15
if [ -s $file ]
then
echo "the $file exists and has data in it"
var=`date'

else
 echo "the $file exists and is empty"
fi

 

检查文件是否可写:

#!/bin/bash
#checking if a file is writeable
logfile=/home/t16test
touch $logfile
chmod u-w $logfile
now=`date +%y%m%d-%H%M`
if [ -w $logfile ]
then
 echo "the program ran at: $now">$logfile
 echo "the first attempt succeeded"
else
echo "the first attempt failed"
fi
chmod u+w $logfile
if [ -w $logfile ]
then
 echo "the program ran at: $now">$logfile
 echo "the second attempt succeeded"
else
echo "the second attempt failed"
fi

 

检查文件是否可执行:

#!/bin/bash
#testing file execution
if [ -x test16 ]
then
echo "you can run the script"
./test16
else
echo "sorry,you can't execute the script"
fi

 

 

 

(4)复合条件查询

if-then语句可以使用复合条件查询。

if [ condition1 ] && [ condition2 ]

[ condition1 ] || [condition2 ]

 

示例:

#!/bin/bash
#testing compound comparsions
if [ -d $HOME ] && [ -w $/HOME/testing ]
then
echo "the file exists and you can write to it"
else
echo "I can't write to the file"
fi

 

(5) if-then的高级特征

双圆括号表示数学表达式。

双方括号表示高级串处理函数

 

(( expression ))

expression可以是:

val++ 后增量

val-- 后减量

++val 前增量

--val 前减量

! 逻辑否定

~ 按位取反

** 取幂

<< 按位左移

>> 按位右移

 

[[ expression ]]

expression主要是与使用的标准字符串比较,提供了模式匹配的功能。

 

示例:

圆括号:

#!/bin/bash
#using double parenthesis
var1=10
if (( $var1**2>90 ))
then
((var2=$var1**2))
echo "the square of $var1 is $var2"
fi

 

方括号:

#!/bin/bash
#using pattern matching
if [[ $USER==r* ]]
then
echo "hello $USER"
else
echo "sorry,i don't know you"
fi

 

(6) case 命令

case命令格式:

 

case variable in

pattern1|pattern2) commands1;;

pattern3)commands2;;

*)default commands;;

esac

 

示例:

#!/bin/bash
#using the case command
case $USER in
rich|root)
echo "welcome,$USER"
echo "please enjoy your visit";;
testing)
echo "special testing account";;
jessica)
echo "don't forget to log off when you're done";;
*)
echo "sorry,you're not allowed here";;
esac

 

 

(7) for命令

格式:

for var in list

do

commands

done

 

读取列表的值,然后进行迭代。

 

 

a.读取列表中的简单值:

#!/bin/bash
#basic for command
for test in Alabama Alaska Arizona Arkansas California Colorado
do
echo the nest state is $test
done

 

b.读取列表中的复杂值:

#!/bin/bash
#another example of how not to user the for command
#当遇到单引号时,需要用双引号,或者用/转 义
for test in I don/'t know if "this'll" work
do
echo "word:$test"
done

 

分析:在上面的脚本中遇到了单引号,don't与this'll必须进行转义或者是用双引号。

 

 

#!/bin/bash
#for 命令是用空格来分隔列表中的值,然后当个别数值中有空格时,应当用双引号包围
for test in Nevadaw "New York" "New Mexico"
do
echo "Now going to $test"
done

 

分析:for命令默认是用空格来分割,如果个别值中有空格时,应当用双引号包围起来。

 

 

c.读取命令中的值:

#!/bin/bash
#reading values from a file
file="states"
for state in `cat $file`
do
echo "visit beautiful $state"
done

 

 

分析: cat $file用的是反引号。

 

 

d.改变字段分割符:

默认情况下,shell将空格,制表符,换行符看成是字段分割符。

如果把字段分割符IFS更改为换行符,则IFS=$'/n'

 

#!/bin/bash
#改变字段分隔符,bash shell的字符分隔符有以下几种: 空格,制表符,换行符
file="states"
IFS=$'/n'
for state in `cat $file`
do
echo "visit beautiful $state"
done
IFS=$IFS.OLD #还原内部字段分隔符

 

e.使用通配符读取目录:

#!/bin/bash
#interate through all the files in a directory
 for file in /home/*
do
if [ -d "$file" ]
then
echo $file is a dir
elif [ -f "$file" ]
then
echo "$file is a file"
fi
done

 

 

(8)C 式for命令

 

格式:

for (( a=1;a<10;a++ ))

单个变量:

#!/bin/bash
#testing the C-style for loop
for ((i=1;i<=10;i++))
do
echo "the next number is $i"
done

 

多个变量:

#!/bin/bash
#multiple variables
for ((a=1,b=10;a<=10;a++,b--))
do
echo "$a-$b"
done

 

(9) while命令

格式:

while test command

do

other commands

done

 

#!/bin/bash
#while command test
var1=10
while [ $var1 -gt 0 ]
do
echo $var1
var1=$[ $var1-1 ]
done

 

 

#!/bin/bash
#testing a multicommand while loop
var1=10
while echo $var1
    [ $var1 -ge 0 ]
do
echo "this is inside the loop"
var1=$[ $var1-1 ]
done

分析:两条测试命令,一条是 echo $var1,另一条是 [ $var1 -ge 0 ]

 

 

 

 

2. 命令行参数

(1)读取参数

向shell脚本传递数据最基本的使用命令行参数(command line parameters).

$0 表示程序名称  $1表示第一个参数  $2表示第二个参数  ..... $9表示第9个参数

如果使用第10个参数就用 ${10}

 

#!/bin/bash
#using one command line parameter
factorial=1
for ((number=1;number<=$1;number++))
do
factorial=$[ $factorial*$number  ]
done
echo the factorial of $1 is $factorial

./test1 5

 

(2)读取程序名称

basename只返回程序名称,不带路径。

 

#!/bin/bash
#testing a multi-function script
name=`basename $0`
if [ $name="addem" ]
then
total=$[ $1+$2 ]
elif  [ $name="multem" ]
then
total=$[ $1*$2 ]
fi
echo the caculated value is $total

 

(3) 参数计数

 

$#存储的是包含命令行参数的个数。

 

#!/bin/bash
if [ $# -ne 2 ]
then
echo Usage:test9 a b
else
total=$[ $1+$2 ]
echo the total is $total
fi

 

 

 

#!/bin/bash
#grabbing the last parameter
params=$#
echo the last param is $params
echo the last parameter is ${!#}

 

${!#}得到最后个命令行参数的值。

当没有任何参数时,即$#等于0,那么${!#}将返回脚本的名称。

 

 

(4)获取所有数据

 

$* 把命令行提供的所有参数当成一个单词处理。

$@ 把命令行提供的所有参数当成同一个字符串中的多个单词进行处理。

 

 

#!/bin/bash
#获得所有数据
#testing s* and S@
count=1
for param in "$*"
do
echo "/S* parameter #$count=$param"
count=$[ $count+1 ]
done

count=1
for param in "$@"
do
echo "/$@ parameter #$count=$param"
count=$[ $count+1 ]
done

结果:

[root@localhost chapter11]# ./test11 a b c d e
/S* parameter #1=a b c d e
$@ parameter #1=a
$@ parameter #2=b
$@ parameter #3=c
$@ parameter #4=d
$@ parameter #5=e

 

3. 获取用户输入

 

read命令接收标准的键盘读入.

(1)基本读取

#!/bin/bash
#testing the read -p option
read -p "please enter your age:" age
days=$[ $age*365 ]
echo "that makes you over $days days old!"

 

read -p允许在命令行中直接指定一个提示。

 

[root@localhost chapter11]# ./test22
please enter your age:10
that makes you over 3650 days old!

 

 

如果不指定变量,那么read命令将数据接收到环境变量REPLY中去。

#!/bin/bash
#testing the REPLY environment variable
read -p "Enter a number:"
factorial=1
for ((count=1;count<=$REPLY;count++))
do
factorial=$[ $factorial*$count ]
done
echo "the factorial of $REPLY is $factorial"

 

(2)计时

read命令,脚本会停止下来等待输入,可以指定一定的时间,当超过这个时间后,继续执行后面的脚本。

read -t

 

 

#!/bin/bash
#timing the data entry
if read -t 5 -p "please enter your name:" name
then
echo "hello $name,welcome to my script"
else
echo
echo "sorry ,two slow"
fi
~              

分析:当超过5秒不输入时,自动执行后面的脚本。

 

read -n1 表示接收到1个字符就退出。

 

#!/bin/bash
#getting just one character of input
read -n1 -p "Do you want to continue[Y/N]?" answer
case $answer in
Y|y)echo
    echo "fine,continue on....";;
N|n)echo
    echo Ok,goodbye
    exit;;
esac
echo "this is the end of the script"

 

(3)默读

当用户的输入不显示在显示器上,即把文本颜色设置成背景颜色即可。 read -s

#!/bin/bash
#hiding input data from the monitor
read -s -p "Enter your password:" pass
echo
echo "Is your password really $pass?"

 

(4)读取文件

 

即从文件中读取数据,

 

#!/bin/bash
#reading data from a file
#通过管道将数据送给read命令
count=1
cat /etc/passwd|while read line
do
echo "Line $count:$line"
count=$[ $count+1 ]
done

 

 

总结:这篇文章主要shell脚本的一些基本结构化命令,如if,for,while.以及命令行参数,$1,$2,$#,$*,$@.最后还有读取用户输入命令read.

接下来的文章主要介绍shell高级编程部分,包括正则表达式,sed,gawk.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值