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

shell学习笔记

2016-03-04 11:05 176 查看


shell学习笔记

shell脚本在linux下开发经常需要用到,shell的脚本可以帮助用户自动化地和操作系统进行交互,起到了提高效率的作用。


调试

学习一门语言,通常需要实战演练编码调试,shell该如何调试呢?使用
bash -x
命令即可。
vi demo.sh
敲入代码:
#!/bin/bash
echo 1;
echo $(date +'%Y-%m-%d');

执行
bash -x demo.sh
将输出
+ echo 1             #代码
1                    #运行结果
++ date +%Y-%m-%d    #嵌套代码
+ echo 2014-10-30    #代码
2014-10-30           #运行结果

可以看到,bash会先输出代码,再输出运行结果,前面带+号表示这是一行shell代码,多个+号表示代码有嵌套逻辑。

更多调试方法见http://coolshell.cn/articles/1379.html


传参

如何从命令外部传递参数到脚本里头?
#!/bin/bash
echo $0       #脚本名
echo $1       #第一个参数
echo ${2}     #第2个参数
echo $#       #参数总数(不含$0)
echo $*       #所有参数(不含$0)

执行
bash demo.sh aa bbb ccc dddd
将输出:
demo.sh
aa
bbb
4
aa bbb ccc dddd

$*
$@
的区别?

$*
$@
都表示传递给函数或脚本的所有参数,不被双引号(
"
"
)包含时,都以”$1”
“$2” … “$n” 的形式输出所有参数。

但是当它们被双引号(
"
"
)包含时,

"$*"
会将所有的参数作为一个整体,以
"$1
$2 … $n"
的形式输出所有参数;

"$@"
会将各个参数分开,以
"$1"
"$2"
"$n"
的形式输出所有参数。


变量


命名

变量的命名语法是:

符合正则
[a-zA-Z-][a-zA-Z\-0-9]
,也就是由大小写字母、数字、
-
符号组成的字符串,不能以数字开头。
非系统缺省关键字,如
PATH



赋值与读取

赋值时等号两边不能带空格,否则会报错。
#字符串变量赋值
name=wang age="100"

#数组变量赋值(3种方式)
array_name1=(value1000 value11 value12 value13)
array_name2=(
value20
value21
value22
value23
)
array_name3[0]=value30
array_name3[1]=value31
array_name3[2]=value32

#双引号内使用变量,单引号不识别内部变量。
echo "双引号:$name is ${age} years old."
echo '单引号:$name is ${age} years old.'

#不使用双引号
echo 不使用双引号:${name} is $age years old.

#读取数组元素
echo "数组元素:${array_name1[2]} ${array_name2[2]} ${array_name3[2]}";

#使用@ 或 * 可以获取数组中的所有元素,例如:
echo "数组@:${array_name1[@]}"
echo "数组*:${array_name1[*]}"

#取得数组元素的个数
echo "数组元素的个数:${#array_name1[@]} ${#array_name3[*]}"

#取得数组单个元素的长度
echo "数组单个元素的长度:${#array_name1[0]}"

将输出
双引号:wang is 100 years old.
单引号:$name is ${age} years old.
不使用双引号:wang is 100 years old.
数组元素:value12 value22 value32
数组@:value1000 value11 value12 value13
数组*:value1000 value11 value12 value13
数组元素的个数:4 3
数组单个元素的长度:9


风格

使用变量可以是
$name
或者
${name}
的形式,注意有别于php字符串内变量
{$name}
${!name}
表示可变变量,类似于php的
$$name


自定义变量往往需要参与各种字符串拼接,如果不加括号,既不利于阅读,也很容易导致逻辑错误。
# Good
prefix="pre"
echo "${prefix}_dir/file"

# Bad
# 会把prefix_dir视为变量名,由于无定义,会输出/file,若设置了set -u,则会报错。
prefix="pre"
echo "$prefix_dir/file"


流程控制


if
else

语法特点为:

条件使用中括号包围:
[[ condition ]]
或者
[
condition ]
(注意中括号内前后都需要带空格)
if
/
elif
condition
前带空格,下一行需要使用
then
语句,也可以通过分号合并成一行
if
[[ condition ]]; then

fi
结尾

if [[ 0 -eq 2 ]]
then
echo 'if'
elif [ 2 ]; then
echo 'else if'
else
echo 'else'
fi


条件表达式

数值

-eq
相等(equal)
-ge
大于等于(greater than or equal)
-gt
大于(greater than)
-ne
不等(not equal)
-le
小于等于(less than or equal)
-lt
小于(less than)

字符串

=
等于
!=
不等于
-z
字符串空
-n
字符串非空

文件状态

-e
存在
-s
存在且非空
-f
存在且普通文件
-r
存在且可读
-w
存在且可写
-x
存在且可执行
-d
存在且目录

逻辑操作

-a
与(and)
-o
或(or)
!

&&
||
用于条件外部

例如
[ 1 -lt 2 ]
echo $?   #true
[ "a" != "a" -o "b" = "c" ]
echo $?   #false
[ "a" != "a" ] || [ "b" = "c" ]
echo $?   #false


switch


for

#从标准输出获取数组
list1=$(echo 'aaa bbb ccc ddd' | awk '{print $1,$2}')
for i in ${list1[@]}
{
echo $i
}

#初始化数组
list2=(1 2 3 4)
for i in ${list2[@]}
do
echo $i
done

#构建循环条件列表
for i in {a..z}
{
for j in {1..3}
{
printf "${i}${j} "
}
}


while


函数

function foo() {    #函数定义
echo $1         #参数1
echo $2         #参数2

local bbb="bbb" #局部变量
echo ${bbb}

return 22;      #返回值
}

foo 123 abc
echo $?

将输出
123
abc
22


命令替换

echo $(pwd)  #语法可读性更好,且支持嵌套
echo `pwd`


算数计算

使用
$(())
, 不使用
let


# i自增1
$(( i += 1 ))
# 复杂的算数计算
min=5
sec=30
echo $(( (min * 60) + sec ))


参考

http://coolshell.cn/articles/1379.html

http://c.biancheng.net/cpp/view/2739.html

http://c.biancheng.net/cpp/view/7002.html

http://lx.wxqrcode.com/post/75.html

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