标签:pat $@ 定义变量 photo 基础 例子 header 示例 iii
对于一台计算机而言,其硬件受系统内核的控制,使用者想要控制计算机,就必须有与系统内核进行通讯的手段。而shell就是使用者与计算机进行通讯的手段之一。从命名上看,shell其实是相对于kernel(内核)而言,指系统与外界(使用者)进行接触的部分,一个提供系统功能给用户使用的软件,它接受来自用户的指令,然后调用相应的应用程序。
为了满足不同的需求,shell提供了两种执行命令方式:
ryeshen@~$ cat /etc/shells
/bin/sh
/bin/bash
/sbin/nologin
/usr/bin/sh
/usr/bin/bash
/usr/sbin/nologin
/bin/tcsh
/bin/csh
/bin/ksh
/bin/zsh
而linux默认是用的解释器是bash。在脚本头可以声明本脚本所使用的解释器,单引号:不保留特殊符号的功能,括号内内容仅作为纯文本进行使用。
如:
ryeshen@~$ echo "I am $name"
I am someone
ryeshen@~$ echo ‘I am $name‘
I am $name
反引号:引号内内容会被作为命令先被执行,命令的结果作为引号的输出。$()的效果与之相同
如:
ryeshen@~$ echo I am `pwd`
I am /home/asl
ryeshen@~$ echo I am $(pwd)
I am /home/asl
ryeshen@~$ echo `echo \$SHELL`
/bin/bash
ryeshen@~$ echo $(echo \$SHELL)
$SHELL
ryeshen@~$ echo `echo \\$SHELL`
$SHELL
ryeshen@~$ echo $(echo \\$SHELL)
\/bin/bash
ryeshen@~$ echo `echo \`
>
ryeshen@~$ echo $(echo \\)
参考的文章的解释是“反引号齐本身就对\进行了转义,保留了齐本身意思,如果我们想在反引号中起到\的特殊意义,我们必须使用2个\来进行表示”。 #shell脚本中#表示行注释
array=(0 1 2 3 4)
array[101]=101 #直接通过 数组名[下标] 就可以对其进行引用赋值。
#如果下标不存在,自动添加新一个数组元素
unset array[101] #使用unset清除指定值
unset array #使用unset清除整个数组
echo ${array[2]} #使用下标获取值
echo ${a[@]} #使用@或*获取数组所有值
echo ${a[*]}
输出结果:
2
0 1 2 3 4
0 1 2 3 4
#${数组名[@或*]:起始位置:长度}
newArray=(${array[@]:1:3}) #先截取数组"1 2 3",再将截取到的数组赋给newArray
for a in ${arr[@]}
do
echo "$a"
done
a="one,two,three,four"
OLD_IFS="$IFS" #使用临时变量保存环境变量IFS的值
IFS="," #给环境变量IFS赋值,这个值用来切割字符串
arr=($a) #字符串切分
IFS="$OLD_IFS" #还原IFS
if …; then
…
elif …; then
…
else
…
fi
注意格式中分号;的使用。ryeshen@~$ if echo "123"; then
> echo "123"
> fi
123
123
( ): 1. 用于数组的初始化
2. 指令群组(command group),即用括号将一组命令包括起
来,这组命令共用一个shell子进程,因此可以分享自定义变量等。
(( )): 相当于命令let,用于算数运算。举个例子:
ryeshen@~$ ((a=1+1)); echo $a
2
ryeshen@~$ ((a=1+1)); echo $a
2
[ ]和[[ ]]的区别:
如上所说,[其实是一个指令,因此使用判断中字符串时最好用双引号括住,
且>、<必须改写成>和\<(>,<是重定向符)。
另外,在使用&&和||时,必须写成 [ cond1 ] && [ cond2 ] 的形式。
[[ ]]则是bash的关键字。可以直接使用>、<、&&、||,如[[ a>1 && b>2 ]]。
[[ ]]中字符串未双引号括住的话,能进行正则表达式匹配。如:
ryeshen@~$ [[ ab == a* ]] && echo "ok"
ok
if语句支持的运算符/操作符:(可以理解为是[指令的参数,就像rm -rf一样)
for var in …; do
do something
done
for (( cond1; cond2; cond3 )) do
do something
done
应用示例:
#输出1 2 3 4 …… 10
for i in $(seq 10); do #这里是用seq指令生成了"1 2 3 …… 10"的字符串
echo $i;
done;
#判断输入的字符串是不是文件名
for file in $*; do # $*指从命令行读入的参数,如输入"test.sh a.xml b.txt c.pdf",则$*=(a.xml b.txt c.pdf)
if [ -f "$file" ]; then
echo "INFO: $file exists"
else
echo "ERROR: $file not exists"
fi
done;
while [ cond1 ] && { || } [ cond2 ] …; do
do something
done
until [ cond1 ] && { || } [ cond2 ] …; do
do somethingdone
应用示例:
# 逐行输出/etc/hosts文件内容
while read line; do
echo $line;
done < /etc/hosts;
# 这里能读入/etc/hosts,是因为<将文件重定向到read指令
case var in
pattern 1 )
… ;;
pattern 2 )
… ;;
*)
… ;;
esac
另外提一下shfit,它可以将入参左移,即进行赋值:$1=$2;$2=$3;$3=$4……
case可以与shfit结合使用,用于根据入参进行处理,举例如下:
shell脚本test.sh:
#!/bin/bash
while [ $# -gt 0 ]; do
case $1 in
-a)
shift; echo a-$1; shift;
;;
-b|-d)
shift; echo bd-$1; shift;
;;
-c)
shift; echo c-$1; shift;
;;
*)
echo unkown; shift;
esac
done
输出:
ryeshen@~$ ./test.sh -a 1 -c 2 -b 3 -d 3
a-1
c-2
bd-3
bd-3
functionname()
{
do something
}
function func()
{
do something
}
func param1 param2 ... # 函数内使用$#,$1等方式获取参数属性和参数,与脚本获取入参类似
func
ret=$? #使用$?获取函数的执行结果
ret=`func` #使用反单引号执行函数并将返回值赋值给变量
+ 脚本中定义的变量可在函数中使用
+ 函数中可用local关键字声明属于自己的,不被外部可见的局部变量
学习过shell的基础知识后,最大的感受是原以为是 shell脚本的特殊用法事实上是有规律可推理的。在此之前,虽然知道[]两边要加空格、使用while read $line;do……done < a.txt可以逐行读入文件等零碎的知识点,但只是知其然却不知其所以然。了解了shell的特殊符号的含义后,才发现这些东西并非只能靠死记硬背,而是有规则可循的。
标签:pat $@ 定义变量 photo 基础 例子 header 示例 iii
原文地址:http://www.cnblogs.com/dunken/p/6367221.html