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.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章