您的位置:首页 > 运维架构 > Shell

Shell脚本学习2

2015-12-07 16:48 531 查看

shell字符串


单引号

str='thisisastring'


单引号字符串的限制:
单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;
单引号字串中不能出现单引号(对单引号使用转义符后也不行)。

双引号

your_name='qinjx'
str="Hello,Iknowyourare\"$your_name\"!\n"


双引号的优点:

双引号里可以有变量

双引号里可以出现转义字符

拼接字符串


your_name="qinjx"
greeting="hello,"$your_name"!"
greeting_1="hello,${your_name}!"
echo$greeting$greeting_1



获取字符串长度


string="abcd"
echo${#string}#输出4



提取字符子串


string="alibabaisagreatcompany"
echo${string:1:4}#输出liba



查找子字符串


string="alibabaisagreatcompany"
echo`exprindex"$string"is`



Shell数组


定义数组


在Shell中,用括号来表示数组,数组元素用“空格”符号分割开。定义数组的一般形式为:
array_name=(value1...valuen)

array_name=(value0value1value2value3)
或者
array_name=(
value0
value1
value2
value3
)
或者array_name[0]=value0
array_name[1]=value1
array_name[2]=value2
[/code]

读取数组

#!/bin/sh
NAME[0]="Zara"
NAME[1]="Qadir"
NAME[2]="Mahnaz"
NAME[3]="Ayan"
NAME[4]="Daisy"
echo"FirstIndex:${NAME[0]}"
echo"SecondIndex:${NAME[1]}"


使用@或*可以获取数组中的所有元素,例如:

${array_name[*]}
${array_name[@]}


获取数组长度

#取得数组元素的个数
length=${#array_name[@]}
#或者
length=${#array_name[*]}
#取得数组单个元素的长度
lengthn=${#array_name[n]}



printf命令


printf输出

printfformat-string[arguments...]

format-string为格式控制字符串,arguments为参数列表。


#format-string为双引号
$printf"%d%s\n"1"abc"
1abc
#单引号与双引号效果一样
$printf'%d%s\n'1"abc"
1abc
#没有引号也可以输出
$printf%sabcdef
abcdef
#格式只指定了一个参数,但多出的参数仍然会按照该格式输出,format-string被重用
$printf%sabcdef
abcdef
$printf"%s\n"abcdef
abc
def
$printf"%s%s%s\n"abcdefghij
abc
def
ghi
j
#如果没有arguments,那么%s用NULL代替,%d用0代替
$printf"%sand%d\n"
and0
#如果以%d的格式来显示字符串,那么会有警告,提示无效的数字,此时默认置为0
$printf"Thefirstprogramalwaysprints'%s,%d\n'"HelloShell
-bash:printf:Shell:invalidnumber
Thefirstprogramalwaysprints'Hello,0'
$



ifelse语句


if语句通过关系运算符判断表达式的真假来决定执行哪个分支。Shell有三种if...else语句:

if...fi语句;

if...else...fi语句;

if...elif...else...fi语句。

#!/bin/sh
a=10
b=20
if[$a==$b]
then
echo"aisequaltob"
else
echo"aisnotequaltob"
fi


#!/bin/sh
a=10
b=20
if[$a==$b]
then
echo"aisequaltob"
elif[$a-gt$b]
then
echo"aisgreaterthanb"
elif[$a-lt$b]
then
echo"aislessthanb"
else
echo"Noneoftheconditionmet"
fi


num1=$[2*3]
num2=$[1+5]
iftest$[num1]-eq$[num2]
then
echo'Thetwonumbersareequal!'
else
echo'Thetwonumbersarenotequal!'
fi

test命令用于检查某个条件是否成立,与方括号([])类似。
[/code]


case...esac


case...esac与其他语言中的switch...case语句类似,是一种多分枝选择结构。

case值in
模式1)
command1
command2
command3
;;
模式2)
command1
command2
command3
;;
*)
command1
command2
command3
;;
esac


case工作方式如上所示。取值后面必须为关键字in,每一模式必须以右括号结束。取值可以为变量或常数。匹配发现取值符合某一模式后,其间所有命令开始执行直至;;。;;与其他语言中的break类似,意思是跳到整个case语句的最后。

echo'Inputanumberbetween1to4'
echo'Yournumberis:\c'
readaNum
case$aNumin
1)echo'Youselect1'
;;
2)echo'Youselect2'
;;
3)echo'Youselect3'
;;
4)echo'Youselect4'
;;
*)echo'Youdonotselectanumberbetween1to4'
;;
esac


#!/bin/bash
option="${1}"
case${option}in
-f)FILE="${2}"
echo"Filenameis$FILE"
;;
-d)DIR="${2}"
echo"Dirnameis$DIR"
;;
*)
echo"`basename${0}`:usage:[-ffile]|[-ddirectory]"
exit1#Commandtocomeoutoftheprogramwithstatus1
;;
esac


$./test.sh
test.sh:usage:[-ffilename]|[-ddirectory]
$./test.sh-findex.htm
$vitest.sh
$./test.sh-findex.htm
Filenameisindex.htm
$./test.sh-dunix
Dirnameisunix
$



for循环


列表是一组值(数字、字符串等)组成的序列,每个值通过空格分隔。每循环一次,就将列表中的下一个值赋给变量。
in列表是可选的,如果不用它,for循环使用命令行的位置参数

for变量in列表
do
command1
command2
...
commandN
done


#!/bin/bash
forFILEin$HOME/.bash*
do
echo$FILE
done


/root/.bash_history
/root/.bash_logout
/root/.bash_profile
/root/.bashrc



while循环


whilecommand
do
Statement(s)tobeexecutedifcommandistrue
done


COUNTER=0
while[$COUNTER-lt5]
do
COUNTER='expr$COUNTER+1'
echo$COUNTER
done


echo'type<CTRL-D>toterminate'
echo-n'enteryourmostlikedfilm:'
whilereadFILM
do
echo"Yeah!greatfilmthe$FILM"
done


break命令

#!/bin/bash
while:
do
echo-n"Inputanumberbetween1to5:"
readaNum
case$aNumin
1|2|3|4|5)echo"Yournumberis$aNum!"
;;
*)echo"Youdonotselectanumberbetween1to5,gameisover!"
break
;;
esac
done


continue命令

#!/bin/bash
while:
do
echo-n"Inputanumberbetween1to5:"
readaNum
case$aNumin
1|2|3|4|5)echo"Yournumberis$aNum!"
;;
*)echo"Youdonotselectanumberbetween1to5!"
continue
echo"Gameisover!"
;;
esac
done


shell函数

function_name(){
listofcommands
[returnvalue]
}

如果你愿意,也可以在函数名前加上关键字function:

functionfunction_name(){
listofcommands
[returnvalue]
}


函数返回值,可以显式增加return语句;如果不加,会将最后一条命令运行结果作为返回值。

Shell函数返回值只能是整数,一般用来表示函数执行成功与否,0表示成功,其他值表示失败。如果return其他数据,比如一个字符串,往往会得到错误提示:“numericargumentrequired”。

如果一定要让函数返回字符串,那么可以先定义一个变量,用来接收函数的计算结果,脚本在需要的时候访问这个变量来获得函数返回值。

#!/bin/bash
funWithReturn(){
echo"Thefunctionistogetthesumoftwonumbers..."
echo-n"Inputfirstnumber:"
readaNum
echo-n"Inputanothernumber:"
readanotherNum
echo"Thetwonumbersare$aNumand$anotherNum!"
return$(($aNum+$anotherNum))
}
funWithReturn
#Capturevaluereturndbylastcommand
ret=$?
echo"Thesumoftwonumbersis$ret!"


Thefunctionistogetthesumoftwonumbers...
Inputfirstnumber:25
Inputanothernumber:50
Thetwonumbersare25and50!
Thesumoftwonumbersis75!


像删除变量一样,删除函数也可以使用unset命令,不过要加上.f选项,如下所示:

$unset.ffunction_name


如果你希望直接从终端调用函数,可以将函数定义在主目录下的.profile文件,这样每次登录后,在命令提示符后面输入函数名字就可以立即调用。


shell函数参数


#!/bin/bash
funWithParam(){
echo"Thevalueofthefirstparameteris$1!"
echo"Thevalueofthesecondparameteris$2!"
echo"Thevalueofthetenthparameteris$10!"
echo"Thevalueofthetenthparameteris${10}!"
echo"Thevalueoftheeleventhparameteris${11}!"
echo"Theamountoftheparametersis$#!"#参数个数
echo"Thestringoftheparametersis$*!"#传递给函数的所有参数
}
funWithParam1234567893473


注意,$10不能获取第十个参数,获取第十个参数需要${10}。当n>=10时,需要使用${n}来获取参数。

特殊变量说明
$#传递给函数的参数个数。
$*显示所有传递给函数的参数。
$@与$*相同,但是略有区别,请查看Shell特殊变量。
$?函数的返回值。

重定向


输出重定向


命令的输出不仅可以是显示器,还可以很容易的转移向到文件,这被称为输出重定向。

命令输出重定向的语法为:

$command>file


>输出重定向会覆盖文件内容

>>输出重定向会不会覆盖文件内容


输入重定向


和输出重定向一样,Unix命令也可以从文件获取输入,语法为:

command<file



重定向深入理解


一般情况下,每个Unix/Linux命令运行时都会打开三个文件:
标准输入文件(stdin):stdin的文件描述符为0,Unix程序默认从stdin读取数据。
标准输出文件(stdout):stdout
的文件描述符为1,Unix程序默认向stdout输出数据。
标准错误文件(stderr):stderr的文件描述符为2,Unix程序会向stderr流中写入错误信息。

如果希望stderr重定向到file,可以这样写:

$command2>file


命令说明
command>file将输出重定向到file。
command<file将输入重定向到file。
command>>file将输出以追加的方式重定向到file。
n>file将文件描述符为n的文件重定向到file。
n>>file将文件描述符为n的文件以追加的方式重定向到file。
n>&m将输出文件m和n合并。
n<&m将输入文件m和n合并。
<<tag将开始标记tag和结束标记tag之间的内容作为输入。

/dev/null文件


如果希望执行某个命令,但又不希望在屏幕上显示输出结果,那么可以将输出重定向到/dev/null:

/dev/null是一个特殊的文件,写入到它的内容都会被丢弃;如果尝试从该文件读取内容,那么什么也读不到。但是/dev/null文件非常有用,将命令的输出重定向到它,会起到”禁止输出“的效果。

$command>/dev/null2>&1



shell文件包含


.filename




sourcefilename


两种方式的效果相同,简单起见,一般使用点号(.),但是注意点号(.)和文件名中间有一空格。

例如,创建两个脚本,一个是被调用脚本subscript.sh,内容如下:

functionHello(){
echo"hellomynameiswht"
words="hiwht"
}
Hello
echo"$words"
echo$?


../test2.sh
echo"$words"


执行结果:

hellomynameiswhthiwht0hiwht
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: