Shell学习笔记
2016-10-05 20:42
169 查看
这是自己学习Shell的一点笔记,主要参考的是http://www.runoob.com/linux/linux-shell.html
作为命令语言,它交互式地解释和执行用户输入的命令;作为程序设计语言,它定义了各种变量和参数,并提供了许多在高级语言中才具有的控制结构,包括循环和分支。
Shell两种执行命令的方式
交互式(Interactive):解释执行用户的命令,用户输入一条命令,Shell就解释执行一条。
批处理(Batch):用户事先写一个Shell脚本(Script),其中有很多条命令,让
其他sh,csh,ksh
#! 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种 Shell。echo命令用于向窗口输出文本。
shell的执行方式有两种:直接运行或者用shell执行。
运行:
没有任何输出。
环境变量
shell变量
完整的表达式要被“包围
条件表达式要放在方括号之间,并且有空格
sh 里没有多行注释
字符串可以用单引号也可以用双引号
单引号字符串的限制: 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的; 单引号字串中不能出现单引号(对单引号使用转义符后也不行)。
双引号的优点: 双引号里可以有变量 双引号里可以出现转义字符
可以单独定义数组的各个分量
可以不使用连续的下标,而且下标的范围没有限制。
转义字符:
它的基本的形式如下:
它的作用是将两个 delimiter 之间的内容(document) 作为输入传递给 command。
注意:
1. 结尾的delimiter 一定要顶格写,前面不能有任何字符,后面也不能有任何字符,包括空格和 tab 缩进。
2. 开始的delimiter前后的空格会被忽略掉。
如果希望屏蔽 stdout 和 stderr,可以这样写:
Shell 文件包含的语法格式如下:
或
创建两个 shell 脚本文件。
test1.sh 代码如下:
test2.sh 代码如下:
接下来,我们为 test2.sh 添加可执行权限并执行:
注:被包含的文件 test1.sh 不需要可执行权限。
Shell介绍
Shell既是一种命令语言,又是一种程序设计语言作为命令语言,它交互式地解释和执行用户输入的命令;作为程序设计语言,它定义了各种变量和参数,并提供了许多在高级语言中才具有的控制结构,包括循环和分支。
Shell两种执行命令的方式
交互式(Interactive):解释执行用户的命令,用户输入一条命令,Shell就解释执行一条。
批处理(Batch):用户事先写一个Shell脚本(Script),其中有很多条命令,让
Shell一次把这些命令执行完,而不必一条一条地敲命令。
常见的Shell
bash:Linux标准的shell其他sh,csh,ksh
第一个shell
#!/bin/bash echo "Hello World!"
#! 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种 Shell。echo命令用于向窗口输出文本。
shell的执行方式有两种:直接运行或者用shell执行。
Shell 变量:Shell 变量的定义、删除变量、只读变量、变量类型
定义变量
定义时直接赋值,使用时用 “$”符号,最好使用花括号。#!/bin/bash myUrl="blog.csdn.net/charles1e" myName="yanke" echo ${myUrl} echo ${myName} myName="Yan Ke" echo ${myName}
只读变量
使用 readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变#!/bin/bash myUrl="www.blog.net/charles1e" readonly myUrl myUrl="www.blog.net/charles"
运行:
./ReadOnlyVariable.sh: line 5: myUrl: readonly variable
删除变量
使用 unset 命令可以删除变量。变量被删除后不能再次使用;unset 命令不能删除只读变量。#!/bin/bash myName="Yan Ke" unset myName echo ${myName}
没有任何输出。
变量类型
局部变量环境变量
shell变量
Shell 特殊变量
Shell替换
Shell 运算符:Shell 算数运算符、关系运算符、布尔运算符、字符串运算符等
算术运算符
表达式和运算符要有空格完整的表达式要被“包围
条件表达式要放在方括号之间,并且有空格
a=10 b=20 val=`expr $a + $b` echo "a+b: ${val}" val=`expr $a - $b` echo "a-b: ${val}" val=`expr $a \* $b` echo "a*b: ${val}" val=`expr $b / $a` echo "b/a: ${val}" val=`expr $b % $a` echo "b%a: $val" if [ $a == $b ] then echo "a is equal to b" fi if [ $a != $b ] then echo "a is not equal to b" fi
关系运算符
#!/bin/bash a=10 b=20 if [ $a -eq $b ] then echo "$a -eq $b : a is equal to b" fi if [ $a -ne $b ] then echo "$a -ne $b : a is not equal to b" fi if [ $a -gt $b ] then echo "$a -gt $b : a is greater than b" else echo "$a -gt $b : a is not greater than b" fi if [ $a -lt $b ] then echo "$a -lt $b : a is lese than b" else echo "$a -lt $b : a is not less than b" fi if [ $a -ge $b ] then echo "$a -ge $b : a is greater or equal to b" else echo "$a -ge $b : a is not greater or equal to b" fi
布尔运算符
!: 非
-o: 或
-a: 与
字符串运算符
=检测两个字符串是否相等,相等返回 true。
!=检测两个字符串是否相等,不相等返回 true。
-z检测字符串长度是否为0,为0返回 true。
-n检测字符串长度是否为0,不为0返回 true。
str检测字符串是否为空,不为空返回 true。
文件测试
#!/bin/bash file="./helloworld.sh" if [ -r $file ] then echo "File has read access" else echo "File does not have read access" fi if [ -w $file ] then echo "File has write access" else echo "File does not have write permission" fi if [ -x $file ] then echo "File has execute permission" else echo "File has no execute permission" fi if [ -f $file ] then echo "File is an ordinary file" else echo "This is a special file" fi if [ -d $file ] then echo "File is a directory" else echo "This ia not a directory" fi if [ -s $file ] then echo "File size is zero" else echo "File size is not zero" fi if [ -e $file ] then echo "File exits" else echo "File does not exit" fi
File has read access File has write access File has execute permission File is an ordinary file This ia not a directory File size is zero File exits
-b file检测文件是否是块设备文件,如果是,则返回 true。
-c file检测文件是否是字符设备文件,如果是,则返回 true。
-d file检测文件是否是目录,如果是,则返回 true。
-f file检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。
-g file检测文件是否设置了 SGID 位,如果是,则返回 true。
-k file检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。
-p file检测文件是否是具名管道,如果是,则返回 true。
-u file检测文件是否设置了 SUID 位,如果是,则返回 true。
-r file检测文件是否可读,如果是,则返回 true。
-w file检测文件是否可写,如果是,则返回 true。
-x file检测文件是否可执行,如果是,则返回 true。
-s file检测文件是否为空(文件大小是否大于0),不为空返回 true。
-e file检测文件(包括目录)是否存在,如果是,则返回 true。
Shell注释
以#开头的行就是注释,会被解释器忽略。
sh 里没有多行注释
Sheel字符串
只有字符串和数字字符串可以用单引号也可以用双引号
单引号字符串的限制: 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的; 单引号字串中不能出现单引号(对单引号使用转义符后也不行)。
双引号的优点: 双引号里可以有变量 双引号里可以出现转义字符
字符串拼接
#!/bin/bash name="yanke" greeting="hello, "${name}"!" greeting1="hello, ${name}!" echo ${greeting} ${greeting1}
字符串长度
$ string="abcd" $ echo ${#string} 4
字符串截取
$ string="Talk is cheap,show me the code!" $ echo ${string:1:4} alk
Shell数组
bash支持一维数组,没有限定数组的大小,数组下标从0开始定义数组
array_name=(value0 value1 value2 value3)
可以单独定义数组的各个分量
可以不使用连续的下标,而且下标的范围没有限制。
读取数组
${array_name[index]}
#!/bin/bash Name[0]='Zara' Name[1]='Qadir' Name[2]='Mahnaz' Name[3]='Ayan' #访问数组中的元素 echo "first index: ${Name[0]}" echo "Second inde;inde;x: ${Name[1]}" #输出所有的元素 echo "First Method:${Name[*]}" echo "Second Method:${Name[@]}" #获取数组的长度 length=${#Name[*]} #或者是 #length=${#Name[@]} #获取单个元素的长度 lengthn=${#Name[2]} echo "The length of Name:${length}" echo "The length of Name[2]:${lengthn}"
first index: Zara Second inde;inde;x: Qadir First Method:Zara Qadir Mahnaz Ayan Second Method:Zara Qadir Mahnaz Ayan The length of Name:4 The length of Name[2]:6
Shell echo命令
#!/bin/bash #echo的使用方法如下: #echo arg #显示转义字符 echo "\"It is a test\"" #显示变量 name="OK" echo "${name} It is a test" #显示换行 echo -e "OK! \n" #-e 开启转义 echo "It's a test" #不换行 echo -e "OK!\c" echo "It's a test" #结果定向到文件 echo "It is a test" > myfile #原样输出字符串 echo '$name\"' #显示命令执行结果 echo `date`
"It is a test" OK It is a test OK! It's a test OK!It's a test $name\" Thu Sep 29 22:08:53 CST 2016
Shell printf命令
#!/bin/bash #printf的格式一般为: #printf format-string [arguments..] #format-string为格式控制字符串 #arguments为参数列表 echo "Hello, Shell!" printf "Hello Shell\n" #printf需要手动换行 ##格式化输出 printf "%-10s %-8s %-4s\n" 姓名 性别 体重kg printf "%-10s %-8s %-4.2f\n" 郭靖 男 66.1234 printf "%-10s %-8s %-4.2f\n" 杨过 男 48.6543 printf "%-10s %-8s %-4.2f\n" 郭芙 女 47.9876 #format-string为双引号 printf "%d %s\n" 1 "abc" #单引号与双引号一样 printf '%d %s\n' 1 "abc" #没有引号也可以输出 printf %s abcdef #格式指指定了一个参数,但是多出的参数仍然会按照这个格式输出 printf %s abc def printf "%s\n" abc def printf "%s %s %S \n" a b c d e f g h i j #如果没有guments,那么%s用NULL替代,%d用 0 替代 printf "%s and %d\n"
转义字符:
\a警告字符,通常为ASCII的BEL字符
\b后退
\c抑制(不显示)输出结果中任何结尾的换行字符(只在
%b格式指示符控制下的参数字符串中有效),而且,任何留在参数里的字符、任何接下来的参数以及任何留在格式字符串中的字符,都被忽略
\f换页(formfeed)
\n换行
\r回车(Carriage return)
\t水平制表符
\v垂直制表符
\\一个字面上的反斜杠字符
\ddd表示1到3位数八进制值的字符。仅在格式字符串中有效
\0ddd表示1到3位的八进制值字符
Shell流程控制
#!/bin/bash #for循环 for loop in 1 2 3 4 5 do echo "The value is : $loop" done #while语句 i=1 while(( ${i}<=5 )) do echo $i let "i++" done #while读取键盘输入 #echo "按 <CTRL-D> 退出" #echo -n "输入你最喜欢的电影名:" #while read FILM #do # echo "是的!${FILM}是一部好电影" #done #until循环:一般很少用,用while就行了 #case多路选择 echo "输入1到4之间的数字" echo -n "你输入的数字为:" read aNum case ${aNum} in 1) echo "你选择了1" ;; 2) echo "你选择了2" ;; 3) echo "你选择了3" ;; 4) echo "你选择了4" ;; *) echo "你没有输入1到4之间的数" ;; esac #跳出循环 #break跳出所有循环 #continue跳出当前循环 while : do echo -n "输入1到5之间的数字:" read num case ${num} in 1|2|3|4|5) echo "你输入的数字为$num" ;; *) echo "你输入的数字不是1到5之间,游戏结束!" break ;; esac done while : do echo -n "输入1到5之间的数字:" read num case ${num} in 1|2|3|4|5) echo "你输入的数字为$num" ;; *) echo "你输入的数字不是1到5之间" continue echo "游戏结束" ;; esac done
Shell函数
$#传递到脚本的参数个数
$*以一个单字符串显示所有向脚本传递的参数
$$脚本运行的当前进程ID号
$!后台运行的最后一个进程的ID号
$@与
$*相同,但是使用时加引号,并在引号中返回每个参数。
$-显示Shell使用的当前选项,与set命令功能相同。
$?显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。
#!/bin/bash #函数定义 #1、可以带function fun() 定义,也可以直接fun() 定义,不带任何参数。 #2、参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0-255))) demoFuc() { echo "Hello world!" } echo "--------函数开始执行-----------" demoFuc echo "--------函数执行完毕-----------" #带有返回值的函数:直接使用return fucWithReturn() { echo "对输入的两个数字相加" echo -n "请输入第一个数字:" read num1 echo -n "请输入第二个数字:" read num2 echo "输入的两个数字为${num1}和${num2}" return $((${num1} + ${num2})) } fucWithReturn echo "和为:$? ." #带有参数的函数:$n的形式传递 funWithParam() { echo "第一个参数为:$1 ." echo "第二个参数为:$2 ." echo "第10个参数为:${10} ." echo "参数的总数为:$# 个." echo "输出所有的参数: $* ." } funWithParam 1 2 3 33 544 5 33 23 23 53 45 22 33
Shell输入/输出重定向
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 之间的内容作为输入。
Here Document
Here Document 是 Shell 中的一种特殊的重定向方式,用来将输入重定向到一个交互式 Shell 脚本或程序。它的基本的形式如下:
command << delimiter document delimiter
它的作用是将两个 delimiter 之间的内容(document) 作为输入传递给 command。
注意:
1. 结尾的delimiter 一定要顶格写,前面不能有任何字符,后面也不能有任何字符,包括空格和 tab 缩进。
2. 开始的delimiter前后的空格会被忽略掉。
/dev/null 文件
如果希望执行某个命令,但又不希望在屏幕上显示输出结果,那么可以将输出重定向到/dev/null:
$ command > /dev/null
/dev/null是一个特殊的文件,写入到它的内容都会被丢弃;如果尝试从该文件读取内容,那么什么也读不到。但是
/dev/null文件非常有用,将命令的输出重定向到它,会起到”禁止输出”的效果。
如果希望屏蔽 stdout 和 stderr,可以这样写:
$ command > /dev/null 2>&1
Shell文件包含
和其他语言一样,Shell 也可以包含外部脚本。这样可以很方便的封装一些公用的代码作为一个独立的文件。Shell 文件包含的语法格式如下:
. filename # 注意点号(.)和文件名中间有一空格
或
source filename
创建两个 shell 脚本文件。
test1.sh 代码如下:
#!/bin/bash # author:菜鸟教程 # url:www.runoob.com url="http://www.runoob.com"
test2.sh 代码如下:
#!/bin/bash # author:菜鸟教程 # url:www.runoob.com #使用 . 号来引用test1.sh 文件 . ./test1.sh # 或者使用以下包含文件代码 # source ./test1.sh echo "菜鸟教程官网地址:$url"
接下来,我们为 test2.sh 添加可执行权限并执行:
$ chmod +x test2.sh
$ ./test2.sh
菜鸟教程官网地址:http://www.runoob.com
注:被包含的文件 test1.sh 不需要可执行权限。
相关文章推荐
- FreeBSD学习笔记02-调整shell
- Shell 编程学习笔记:脚本输入参数
- shell学习笔记二--工具 推荐
- SHELL学习笔记----IF条件判断,判断条件
- shell学习笔记三--脚本初步
- Linux学习笔记-shell命令[转帖]
- shell学习笔记一--总括
- shell学习笔记1-基本shell命令
- shell学习笔记三 分支结构
- 写得蛮好的linux学习笔记(压缩命令,vi一般用法,认识SHELL,正规表示法)
- Shell学习笔记--查看文本
- Shell学习笔记(三)
- shell学习笔记(一)
- shell学习笔记—文本处理
- Linux学习笔记-shell命令[转帖]
- shell学习笔记【原创】
- shell学习笔记一--总括
- shell shell学习笔记001--什么是shell?
- shell学习笔记一 变量
- shell学习笔记二 参数和环境变量