频道栏目
首页 > 资讯 > 其他综合 > 正文

Shell学习笔记

16-07-15        来源:[db:作者]  
收藏   我要投稿

1 给变量赋值时,“=”两边都不能留空格
2 Shell 的默认赋值是字符串赋值

    var=1  
    var=$var+1  
    echo $var  
打印出来的是1+1而不是2。  

3 [ -f "somefile" ] :判断是否是一个文件
[ -x "/bin/ls" ] :判断/bin/ls是否存在并有可执行权限
[ -n "$var" ] :判断$var变量是否有值
[ "$a" = "$b" ] :判断a和b是否相等
4 if 语句:
if …; then

elif …; then

else

if
下面是一个简单的if语句:

        #!/bin/bash  
    if [ ${SHELL} = "/bin/bash" ] ; then  
       echo "your login shell is the bash (bourne again shell)"  
    else  
       echo "your login shell is not bash but ${SHELL}"  
    fi 

5 case 语句
case表达式可以用来匹配一个给定的字符串,而不是数字(可别和C语言里的switch…case混淆)。
case … in
…)
do something here ;;
esac
file命令可以辨别出一个给定文件的文件类型,如:file lf.gz,其输出结果为:
lf.gz: gzip compressed data, deflated, original filename,
last modified: Mon Aug 27 23:09:18 2001, os: Unix
我们利用这点写了一个名为smartzip的脚本,该脚本可以自动解压bzip2, gzip和zip 类型的压缩文件:

 #!/bin/bash  
 ftype="$(file "$1")"  
 case "$ftype" in  
 "$1: Zip archive"*)  
    unzip "$1" ;;  
 "$1: gzip compressed"*)  
    gunzip "$1" ;;  
 "$1: bzip2 compressed"*)  
    bunzip2 "$1" ;;  
 *) echo "File $1 can not be uncompressed with smartzip";;  
 esac  

你可能注意到上面使用了一个特殊变量$1,该变量包含有传递给该脚本的第一个参数值。也就是说,当我们运行:

../201510/GridViewLiveTiles.html  

$1 就是字符串 articles.zip。
6 Bash只提供一维数组,并且没有限制数组大小
7 对数组元素赋值
对数组元素赋值的一般形式是:数组名[下标]=值,例如:

$ city[0]=Beijing
$ city[1]=Shanghai
$ city[2]=Tianjin

一个数组的各个元素可以利用上述方式一个元素一个元素地赋值,也可以组合赋值。定义一个数组并为其赋初值的一般形式是:

数组名=(值1 值2 … 值n)
其中,各个值之间以空格分开。例如:

$ A=(this is an example of shell script)
$ echo ${A[0]} ${A[2]} ${A[3]} ${A[6]}
this an example script
$ echo ${A[8]}

由于值表中初值共有 7 个,所以 A 的元素个数也是 7 。 A[8] 超出了已赋值的数组 A 的范围,就认为它是一个新元素,由于预先没有赋值,所以它的值是空串。

若没有给出数组元素的下标,则数组名表示下标为 0 的数组元素,如 city 就等价于 city[0] 。

8 如果要列出数组中的所有元素,使用*或@作下标
9 获取数组元素的个数

$ echo ${#A[*]}

10 数值比较中常见的比较符

= -eq
!= -ne(not equal)
> -gt(greater than)
>= -ge(greater than or equal)
< -lt(less than)
<= -le 

11 测试文件属性的常见参数
-r; -w; -x; -f; -d
12 字符串长度属性
-z(字符串长度为零)
-n(非零)
13 条件测试命令 test
语法:test 表达式 如果表达式为真,则返回真,否则,返回假。

$ test var1 -gt var2
$ test -r filename
$ test -z s1 如果串 s1 长度为零,返回真。

14 有限循环命令for…in…
语法:

for 变量名 in 字符串表
do
命令表
done
举例:

FILE="test1.c myfile1.f pccn.h"
for i in $FILE
do
    cd ./tmp
    cp $i $i.old
    echo "$i copied"
done

for var in sss
sss是串行,串行是一些字符串的组合。for…in…的运作方式是把sss中的元素依次取出放入变量var中,并执行do和done之间的命令
15 判断字符的类型
范例:数字或者数字组合

能够返回结果,即程序退出状态是0,说明属于这种类型,反之不然

$ i=5;j=9423483247234;
$ echo $i | grep [0-9]*
5
$ echo $j | grep [0-9]*
9423483247234
$ echo $j | grep [0-9]* >/dev/null
$ echo $?
0

范例:字符组合(小写字母、大写字母、两者的组合)

$ c="A"; d="fwefewjuew"; e="fewfEFWefwefe"
$ echo $c | grep [A-Z]
A
$ echo $d | grep "[a-z]*"
fwefewjuew
$ echo $e | grep "[a-zA-Z]*"
fewfEFWefwefe

字母和数字的组合

$ ic="432fwfwefeFWEwefwef"
$ echo $ic | grep "[0-9a-zA-Z]*"
432fwfwefeFWEwefwef

范例:空格或者 Tab 键等

$ echo " " | grep " "
$ echo -e "\t" | grep "[[:space:]]" #[[:space:]]会同时匹配空格和TAB键
$ echo -e " \t" | grep "[[:space:]]"

$ echo -e “\t” | grep “” #为在键盘上按下TAB键,而不是字符
范例:匹配邮件地址

$ echo "test2007@lzu.cn" | grep "[0-9a-zA-Z\.]*@[0-9a-zA-Z\.]"
test2007@lzu.cn

16 /dev/null 和 /dev/zero 是非常有趣的两个设备,它们都犹如一个黑洞,什么东西掉进去都会消失殆尽;后者则是一个能源箱,你总能从那里取到 0,直到你退出。
17 ?和@ 的区别
?所有参数列表。如”*"用「"」括起来的情况、以"12 … n”的形式输出所有参数。@
所有参数列表。如”@"用「"」括起来的情况、以"1” “2"…"n” 的形式输出所有参数。
示例:

1 #!/bin/bash
2 #
3 printf "The complete list is %s\n" "$*"

结果:

[Aric@localhost ~]$ bash params.sh 123456 QQ
The complete list is 123456 QQ
1 #!/bin/bash
 2 #
 3 printf "The complete list is %s\n" "$@"

结果:

[Aric@localhost ~]$ bash params.sh 123456 QQ
The complete list is 123456
The complete list is QQ

因为有两个参数,所以”$@”输出了两次
18 字符串的长度
范例:计算某个字符串的长度
即所有字符的个数[这计算方法是五花八门,择其优者而用之]

$ var="get the length of me"
$ echo ${var}     # 这里等同于$var
get the length of me
$ echo ${#var}
20
$ expr length "$var"
20
$ echo $var | awk '{printf("%d\n", length($0));}'
20
$ echo -n $var |  wc -c
20

19 字符串操作_取子串
取子串的方法主要有两种:直接到指定位置求子串,字符匹配求子串。

范例:按照位置取子串

比如从什么位置开始,取多少个字符

$ var="get the length of me"
$ echo ${var:0:3}
get
$ echo ${var:(-2)}   # 方向相反
me
$ echo `expr substr "$var" 5 3` #记得把$var引起来,否则expr会因为空格而解析错误
the
$ echo $var | awk '{printf("%s\n", substr($0, 9, 6))}'
length
awk 把 $var 按照空格分开为多个变量,依次为 $1,$2,$3,$4,$5

$ echo $var | awk '{printf("%s\n", $1);}'
get
$ echo $var | awk '{printf("%s\n", $5);}'
me

范例:匹配字符求子串

用 Bash 内置支持求子串

$ echo ${var%% *} #从右边开始计算,删除最左边的空格右边的所有字符
get
$ echo ${var% *} #从右边开始计算,删除第一个空格右边的所有字符
get the length of
$ echo ${var##* }  #从左边开始计算,删除最右边的空格左边的所有字符
me
$ echo ${var#* }  #从左边开始计算,删除第一个空格左边的所有字符
the length of me

可以这么理解 #和%是从左边还是右边开始计算的flag,${var#* },从左边开始计算,删除一个"*"和一个" "(空格);${var##* }从左边开始计算,删除n个"*"" "${var% *}从右边开始计算,删除一个" ""*";${var%% *}从右边开始计算,删除n个" ""*"
对于字符串的截取,实际上还有一些命令,如果 head,tail 等可以实现有意思的功能,可以截取某个字符串的前面、后面指定的行数或者字节数。例如:

$ echo "abcdefghijk" | head -c 4
abcd
$ echo -n "abcdefghijk" | tail -c 4
hijk

20 字符串操作_查询字串
子串查询包括:返回符合某个模式的子串本身和返回子串在目标串中的位置。
范例:查询子串在目标串中的位置

貌似仅仅可以返回某个字符或者多个字符中字符第一次出现的位置

$ var="get the length of me"
$ expr index "$var" t
3

awk 却能找出字串,match 还可以匹配正则表达式

$ echo $var | awk '{printf("%d\n", match($0,"the"));}'
5

21 字符串操作_子串替换
用 {} 运算符

$ var="get the length of me"
$ echo ${var/ /_}        #把第一个空格替换成下划线
get_the length of me
$ echo ${var// /_}        #把所有空格都替换成了下划线了
get_the_length_of_me

用 awk,awk 提供了转换的最小替换函数 sub 和全局替换函数 gsub,类似 / 和 //

$ echo $var | awk '{sub(" ", "_", $0); printf("%s\n", $0);}'
get_the length of me
$ echo $var | awk '{gsub(" ", "_", $0); printf("%s\n", $0);}'
get_the_length_of_me

用 sed ,子串替换可是 sed 的特长

$ echo $var | sed -e 's/ /_/'    #s <= substitude
get_the length of me
$ echo $var | sed -e 's/ /_/g'    #看到没有,简短两个命令就实现了最小匹配和最大匹配g <= global
get_the_length_of_me

sed 还有专门的插入指令,a 和 i,分别表示在匹配的行后和行前插入指定字符

$ echo $var | sed '/get/a test'
get the length of me
test
$ echo $var | sed '/get/i test'
test
get the length of me

22 重定向
linux shell下常用输入输出操作符是:

标准输入 (stdin) :代码为 0 ,使用 < 或 << 标准输出 (stdout):代码为 1 ,使用 > 或 >> 标准错误输出(stderr):代码为 2 ,使用 2> 或 2>>

实例:

#将错误输出信息关闭掉
[chengmo@centos5 shell]$ ls test.sh test1.sh 2>&-
test.sh
[chengmo@centos5 shell]$ ls test.sh test1.sh 2>/dev/null
test.sh
#&[n] 代表是已经存在的文件描述符,&1 代表输出 &2代表错误输出 &-代表关闭与它绑定的描述符
#/dev/null 这个设备,是linux 中黑洞设备,什么信息只要输出给这个设备,都会给吃掉 

#关闭所有输出
[chengmo@centos5 shell]$ ls test.sh test1.sh  1>&- 2>&- 
#关闭 1 ,2 文件描述符
[chengmo@centos5 shell]$ ls test.sh test1.sh  2>/dev/null 1>/dev/null
#将1,2 输出转发给/dev/null设备 
[chengmo@centos5 shell]$ ls test.sh test1.sh >/dev/null 2>&1
#将错误输出2 绑定给 正确输出 1,然后将 正确输出 发送给 /dev/null设备  这种常用

[chengmo@centos5 shell]$ ls test.sh test1.sh &>/dev/null #& 代表标准输出 ,错误输出 将所有标准输出与错误输出 输入到/dev/null文件

注意:

1、shell遇到”>”操作符,会判断右边文件是否存在,如果存在就先删除,并且创建新文件。不存在直接创建。 无论左边命令执行是否成功。右边文件都会变为空。

23 命令替换
语法

`command` 使用反引号

下面的例子中,将命令执行结果保存在变量中:

#!/bin/bash
DATE=`date`
echo "Date is $DATE"
USERS=`who | wc -l`
echo "Logged in user are $USERS"
UP=`date ; uptime`
echo "Uptime is $UP"

24
变量替换

变量替换可以根据变量的状态(是否为空、是否定义等)来改变它的值

可以使用的变量替换形式:
形式 说明

${var} 变量本来的值

${var:-word} 如果变量 var 为空或已被删除(unset),那么返回 word,但不改变 var 的值。
${var:=word} 如果变量 var 为空或已被删除(unset),那么返回 word,并将 var 的值设置为 word。
${var:?message} 如果变量 var 为空或已被删除(unset),那么将消息 message 送到标准错误输出,可以用来检测变量 var 是否可以被正常赋值。
若此替换出现在Shell脚本中,那么脚本将停止运行。
${var:+word} 如果变量 var 被定义,那么返回 word,但不改变 var 的值。

请看下面的例子:

#!/bin/bash

echo ${var:-"Variable is not set"}
echo "1 - Value of var is ${var}"

echo ${var:="Variable is not set"}
echo "2 - Value of var is ${var}"

unset var
echo ${var:+"This is default value"}
echo "3 - Value of var is $var"

var="Prefix"
echo ${var:+"This is default value"}
echo "4 - Value of var is $var"

echo ${var:?"Print this message"}
echo "5 - Value of var is ${var}"

运行结果:

Variable is not set
1 - Value of var is
Variable is not set
2 - Value of var is Variable is not set
3 - Value of var is
This is default value
4 - Value of var is Prefix
Prefix
5 - Value of var is Prefix

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

如果一定要让函数返回字符串,那么可以先定义一个变量,用来接收函数的计算结果,脚本在需要的时候访问这个变量来获得函数返回值。
像删除变量一样,删除函数也可以使用 unset 命令,不过要加上 .f 选项,如下所示:
复制纯文本新窗口

$unset .f function_name

如果你希望直接从终端调用函数,可以将函数定义在主目录下的 .profile 文件,这样每次登录后,在命令提示符后面输入函数名字就可以立即调用。
26 引号
单引号字符串的限制:
单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;
单引号字串中不能出现单引号(对单引号使用转义符后也不行)。
双引号的优点:
双引号里可以有变量
双引号里可以出现转义字符
27 文件包含
像其他语言一样,Shell 也可以包含外部脚本,将外部脚本的内容合并到当前脚本。

Shell 中包含脚本可以使用:

. filename

source filename

28 IFS
内部字段分隔符(Internal Field Seprator)

相关TAG标签
上一篇:Python语言下的机器学习库
下一篇:VMware安装CentOS以及CentOS的一些配置
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站