shell基础知识总结
1. shell
对于一台计算机而言,其硬件受系统内核的控制,使用者想要控制计算机,就必须有与系统内核进行通讯的手段。而shell就是使用者与计算机进行通讯的手段之一。从命名上看,shell其实是相对于kernel(内核)而言,指系统与外界(使用者)进行接触的部分,一个提供系统功能给用户使用的软件,它接受来自用户的指令,然后调用相应的应用程序。
为了满足不同的需求,shell提供了两种执行命令方式:
- a. 交互式:解释并执行用户输入的命令或者自动地解释和执行预先设定好的一连串的命令。
- b. 程序设计式:作为一种脚本语言,提供变量、控制结构和函数,再通过解释器解释并执行。
Linux上常见的shell有sh、bash、ksh、tcsh等,不同解释器在某些语法的执行方面可能有些不同。通过查看/etc/shells文件就可以知道本系统所支持的shell解释器类型。如shells的文件内容如下: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。在脚本头可以声明本脚本所使用的解释器,
声明方式: #!/bin/bash
2. 变量
a. 赋值
- 赋值方式:variable_name = variable_value
- 等号两边不能有空格符;
- 增加变量内容:PATH=”$PATH”:/home/bin
- 取消变量:unset variable_name
- 变量类型:可以使用declare [[-/+]aixr] [name[=value] …],其中-表示赋予变量属性,+表示去除变量属性,a-数组,i-整数,r-只读,x-环境变量
b. 自定义变量与环境变量
- 使用“=”赋值得到的自定义变量,这个变量的作用域为当前shell进程。
- 使用export命令可以声明一个环境变量,一个环境变量的作用域为当前shell进程及
其shell子进程(subshell)。 - 在启动shell进程的时候,shell会从文件中加载一些默认的环境变量到shell进程中,
如HOME、PATH等。 - 用env可以查看当前所有的环境变量,set则可以看所有的环境变量和自定义变量。
p.s. 关于子shell进程
- i. 创建一个shell子进程的方式包括但不限于:
- 使用&提交后台作业。后台作业于subshell中运行;
- 使用管道。|左右的命令均在独立的subshell中运行;
- 括号操作符。()中的命令在subshell中运行;
- 执行外部脚本或程序。
- ii. subshell可以继承shell父进程的属性包括:当前的工作目录、环境变量、标准输入输出和错误输出、所有已打开的文件描述符、忽略的信号。
- iii. subshell对环境变量的修改对shell父进程不可见。
- i. 创建一个shell子进程的方式包括但不限于:
c. shell中的单引号、双引号和反引号
- 双引号:保留$的变量扩展功能,使用变量时会$后的变量转变为变量的值。在双引号中可以使用转义符\将$转变为纯文本符号。使用双引号后不支持正则匹配。
单引号:不保留特殊符号的功能,括号内内容仅作为纯文本进行使用。
如: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
p.s. 反引号与$()的一点区别
— 参考自http://km.oa.com/articles/show/310289
先来看几个例子: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个\来进行表示”。
对此我的理解是,在反引号中,\表示续行(见倒数第二个例子),\才表示转义符。而在$()中,\本身就起到转义符的效果。3. 数组
a. 赋值
#shell脚本中#表示行注释
array=(0 1 2 3 4)
array[101]=101 #直接通过 数组名[下标] 就可以对其进行引用赋值。
#如果下标不存在,自动添加新一个数组元素
unset array[101] #使用unset清除指定值
unset array #使用unset清除整个数组
b. 取值
echo ${array[2]} #使用下标获取值
echo ${a[@]} #使用@或*获取数组所有值
echo ${a[*]}
输出结果:
2
0 1 2 3 4
0 1 2 3 4
c. 截取
#${数组名[@或*]:起始位置:长度}
newArray=(${array[@]:1:3}) #先截取数组"1 2 3",再将截取到的数组赋给newArray
d. 遍历
for a in ${arr[@]}
do
echo "$a"
done
e. 拆分字符串到数组
a="one,two,three,four"
OLD_IFS="$IFS" #使用临时变量保存环境变量IFS的值
IFS="," #给环境变量IFS赋值,这个值用来切割字符串
arr=($a) #字符串切分
IFS="$OLD_IFS" #还原IFS
4. 语法
a. if
if语句的格式如下:
if …; then
…
elif …; then
…
else
…
fi
注意格式中分号;的使用。
if的判断语句中,方括号和逻辑运算符两边都必须有空格(“]”的右边除外)。p.s. []必须有空格的原因
“[“ 是linux系统中的指(试试whereis [),用法与test相同,但最后一个参数必须是 “]”。这也是为什么then前面要加分号”;”的原因。相似地可以推出,if后面可以接其他指令,利用其返回值进行判断,当返回值为0时if才判断为true
如:ryeshen@~$ if echo "123"; then
> echo "123"
> fi
123
123
p.s. (),(()),[]和[[]]
( ): 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一样)
b. for
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;
p.s. 关于脚本的传入参数
- $#是入参的个数,
- $@和$*是当前所有的入参
- $0是脚本的名字
- $1是第一个入参,$2是第二个入参,以此类推
pp.s. $@和$*的区别
- 不被双引号””括起来时,$@和$*一致。
- 被双引号””括起来时:
- “$*”表示“$0IFS$1IFS$2”。举个例子,设IFS为“-”,入参为“1 2 3”,则输出为“1-2-3”。
- “$@”与$@相同
```
c. while和until
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指令
d. case
case var in
pattern 1 )
… ;;
pattern 2 )
… ;;
*)
… ;;
esac
- case行尾必须为单词“in”,每一个模式必须以右括号“)”结束。
- ;; 表示命令序列结束。
- pattern可以使用匹配符,如
- a|b: a或者b
- *:匹配任意长度的任意字符;
- ?:匹配任意单个字符;
- [-]:范围匹配
另外提一下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
e. function
- 函数定义
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的特殊符号的含义后,才发现这些东西并非只能靠死记硬背,而是有规则可循的。
shell基础知识总结的更多相关文章
- Linux shell基础知识(上)
Linux shell基础知识(上) 目录 一.shell介绍 二.命令历史 三.命令补全和别名 四.通配符 五.输入输出重定向 六.管道符和作业控制 七.shell变量 八.环境变量配置文件 九.b ...
- Linux Shell 基础知识(一)
1. 本文知识结构 2. shell 基础知识 2.1 shell 简单介绍 GNU bash shell 能提供对 Linux 系统的交互式访问,一般来说,使用快捷键 Ctrl + Alt + ...
- Shell 基础知识和总结
调试脚本 检查脚本语法错误 bash -n /path/to/some_script 调试执行 bash -x /path/to/some_script shell里的变量 本地变量:只对当前shel ...
- shell基础知识---与监听服务器长连接端口状态
从未写过脚本我的最近接了俩脚本的需求,就在这分享一下我的我学到基础知识主要就四部分内容 一.变量 变量的定义 string='字符串' string="字符串" num=808st ...
- shell基础知识讲解
第1章 shell基础 1.1 什么叫做shell编程 shell编程也叫做bash高级编程语法 1.2 常见的shell命令解释器 bash redhat和centos使用 d ...
- shell基础知识
Shell 学习基础 1.组合命令的符号 管道,将前面一个命令的结果作为后面一个命令的输入 分号,顺序执行用分号分割的命令 重定向,重定向包括三种:输入重定向.输出重定向.错误重定向,以7个不同的符号 ...
- shell从入门到精通进阶之一:Shell基础知识
1.1 简介 Shell是一个C语言编写的脚本语言,它是用户与Linux的桥梁,用户输入命令交给Shell处理,Shell将相应的操作传递给内核(Kernel),内核把处理的结果输出给用户. 下面是处 ...
- Shell基础知识和编程规范
一,Shell环境查看 1.1 查看系统Shell支持情况 [root@linux-node1 ~]# cat /etc/shells /bin/sh /bin/bash /sbin/nologin ...
- shell基础知识5-函数
函数的定义 function fname(){ } 或者 function_name(){ } 对于简单的函数,甚至可以是这样做 fname() { statement; } 函数调用 直接写函数名即 ...
随机推荐
- 最新PHPcms9.6.0 任意文件上传漏洞
在用户注册处抓包: 然后发送到repeater POC: siteid=&modelid=&username=z1aaaac121&password=aasaewee311as ...
- DIV中display和visibility属性差别
DIV中display和visibility属性差别 DIV中display和visibility属性差别还是挺大的,虽然Visibility和Display属性都可以达到隐藏页面元素的目的,但它们的 ...
- 关于Unity中的几何体,材质和FBX模型
一.创建几何体的类型 1: 创建平面 Plane;2: 创建立方体 Cube;3: 创建球体 Sphere;4: 创建胶囊体 Capsule;5: 创建圆柱体 Cylinder;6: 3D文字 3D ...
- Mybatis实现了接口绑定,使用更加方便。
1.Mybatis实现了接口绑定,使用更加方便. 在ibatis2.x中我们需要在DAO的实现类中指定具体对应哪个xml映射文件, 而Mybatis实现了DAO接口与xml映射文件的绑定,自动为我们生 ...
- 【BZOJ】1671: [Usaco2005 Dec]Knights of Ni 骑士(bfs)
http://www.lydsy.com/JudgeOnline/problem.php?id=1671 从骑士bfs一次,然后从人bfs一次即可. #include <cstdio> # ...
- [转]Loadrunner Error code 10053 & Tomcat 连接器(connector)优化
LoadRunner提示错误:Error : socket0 - Software caused connection abort. Error code : 10053. 在今天的测试过程中发现,s ...
- The user specified as a definer (”@’%') does not exist解决方法
报错如下: 遇见这个问题,网上都是千篇一律,改权限( grant all privileges on *.* to root@”%” identified by “.”; flush privil ...
- mybatis总结(三)之多表查询
上一节,已经把实体类和配置文件都写过了,这节课直接添加几个方法吧 在DeptMapper.xml文件中添加 <!-- 多表查询(1对多) ,通过部门编号,查询出部门所在的员工姓名,部门名,部门编 ...
- DecimalFormat 四舍五入Float类型的坑
今天又踩了一个坑,使用DecimalFormat来完毕四舍五入.可是传入的是float类型,几轮測试才发现一个问题,传入的float会被转为double类型.大家都知道float是4位,double是 ...
- HDU 1058 Humble Numbers (动规+寻找丑数问题)
Humble Numbers Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) T ...