L7.1 linux shell总结

linux shell总结


本文从以下几个方面详细总结bash shell相关内容:

1,shell程序的运行原理

2,shell编程中所涉及到的所有知识点:

    书写格式,执行,变量,语法,命令状态


1,shell程序的运行原理;

什么是shell?

sehll是命令语言、命令解释程序及程序设计语言的统称。系统的shell作为操作系统的外壳,为用户提供使用操作系统的接口。其基本功能是解释并执行用户打入的各种命令,实现用户与Linux核心的接口.

如果把Linux内核想象成一个球体的中心,shell就是围绕内核的外层。当从shell或其他程序向Linux传递命令时,内核会做出相应的反应。 

shell是一个命令语言解释器,它拥有自己内建的shell命令集,shell也能被系统中其他应用程序所调用。

用户在提示符下输入的命令都由shell先解释然后传给Linux核心。 有一些命令,比如改变工作目录命令cd,是包含在

shell内部的。还有一些命令,例如拷贝命令cp和移动命令rm,是存在于文件系统中某个目录下的单独的程序


shell工作原理:

系统初启后,核心为每个终端用户建立一个进程去执行Shell解释程序。它的执行过程基本上按如下步骤:

(1)读取用户由键盘输入的命令行。


(2)分析命令,以命令名作为文件名,并将其它参数改造为系统调用execve()内部处理所要求的形式。(词法分析: 命令,选项,参数)


(3)终端进程调用fork()建立一个子进程。


(4)终端进程本身用系统调用wait4()来等待子进程完成(如果是后台命令,则不等待)。当子进程运行时调用execve(),子进程根据文件名(即命令名)到目录中查找有关文件(这是命令解释程序构成的文件),将它调入内存,执行这个程序(解释这条命令)。


(5)如果命令末尾有&号(后台命令符号),则终端进程不用系统调用wait4( )等待,立即发提示符,让用户输入下一个命令,转⑴。如果命令末尾没有&号,则终端进程要一直等待,当子进程(即运行命令的进程)完成处理后终止,向父进程(终端进程)报告,此时终端进程醒来,在做必要的判别等工作后,终端进程发提示符,让用户输入新的命令,重复上述处理过程...


另外:

shell的另一个重要特性是它自身就是一个解释型的程序设计语言,shell程序设计语言支持绝大多数在高级语言中能见到的程序元素,如函数、变量、数组和程序控制结构。


当普通用户成功登录,系统将执行一个称为shell的程序。正是shell进程提供了命令行提示符。作为默认值(Linux系统默认的shell是BASH),对普通用户用“$”作提示符,对超级用户(root)用“#”作提示符。 一旦出现了shell提符,就可以键入命令名称及命令所需要的参数。shell将执行这些命令。如果一条命令花费了很长的时间来运行,或者在屏幕上产生了大量的输出,可以从键盘上按ctrl+c发出中断信号来中断它(在正常结束之前,中止它的执行)。 当用户准备结束登录对话进程时,可以键入logout命令、exit命令或文件结束符(EOF)(按ctrl+d实现),结束登录。


bash过程式编程:

        顺序执行:逐个执行

        选择执行:只执行其中一个分支

        循环执行:一段代码要执行0,1或多遍


2、shell编程中所涉及到的所有知识点;

shell所涉及重要知识点,依次介绍脚本:

书写,执行,变量,语法,命令状态,以下详细说明


书写,执行方式:

脚本:文本文件

运行脚本:事实上是运行一个bash进程,此进程负责从脚本文件中读取一个执行逻辑,而后由bash进程负责解析并运行此逻辑;

启动脚本:

    (1) # bash /PATH/TO/SCRIPT_FILE

    (2) 一个执行权限, 

# ./PATH/TO/SCRIPT_FILE 

shebang:(#!/bin/bash)解释此脚本的shell路径,shell有多种类型,如:sh,csh,ksh,tcsh,..,bash引用最为广泛。

#!/bin/bash

第一行:顶格给出shebang

单行注释:#

        多行注释:

            : << 字符  #这里的字符可以是数字或者是字符都可以

            语句1

            语句2

            语句3

            语句4

            字符  

bash的常用选项:

        -n: 检查脚本中的语法错误;

        -x:调试执行脚本;

    

示例:

[root@os01 ~]# cat t1.sh 
#!/bin/bash
echo 1
#echo 2
echo 3
echo 4
echo 5
[root@os01 ~]# ./t1.sh     #单行注释的2没有输出
1
3
4
5
~
#多行注释
[root@os01 ~]# cat t1.sh 
#!/bin/bash
echo 1
:<<EOF                         #多行注释开始
echo 2
echo 3
echo 4
EOF                           #多行注释结束
echo 5
[root@os01 ~]# bash -n t1.sh  
[root@os01 ~]#         #测试脚本,没有结果证明没有语法错误
[root@os01 ~]# bash -x t1.sh#注释的多行,2,3,4没有输出
+ echo 1
1
+ :
+ echo 5
5



变量

变量概念:

可变化的量,命名内存空间 (赋值后保存在内存空间)

bash环境:

    本地变量:当前shell进程;

    环境变量:当前shell进程及其子进程;

    局部变量:某个函数执行过程;

    位置参数变量:在脚本中引用传递给脚本的参数;在函数中引用传递给函数的参数;

    特殊变量:$?, $*, $@, $#, $$


变量类型:

    数值,字符;

    数值:

    整数

    浮点数

    字符:

        ASCII

    比如:120: 字符会识别为1,2,0;数值会识别为:120 

 

变量类型的作用:

    存储空间:比如声明变量为数值类型可以节省存储空间

    运算:运算必须为数值类型

    存储格式


语言对变量类型的支持力度:

    强类型:严格区分变量类型

    弱类型:变量类型不严格区分;

    默认存储机制:bash为字符

    bash的变量使用特点:弱类型、无须事先声明;


(1)本地变量

本地变量定义:

   name=value

    name: 变量名

    =:赋值符号

    value:值

    变量名:只能包含数字、字母和下划线;且不能以数字开头;

    引用变量:${name}, $name


示例:

#本地变量定义与使用,只对当前shell生效,logout后,或者在子进程时shell无效。
[root@os01 ~]# test="bird"           #变量test赋值为bird
[root@os01 ~]# echo "this is a $test"
this is a bird#引用变量成功
[root@os01 ~]# set |egrep '\btest\b'  #查看本地变量test
test=bird
[root@os01 ~]# bash#进入子进程(子shell)
[root@os01 ~]# echo "this is a $test"
this is a #子进程没有继承父进程$test,这里为空
#变量引用注意事项,当变量后直接跟字符串时,需要使用{}让shell能够识别变量名
[root@os01 ~]# test=mage
[root@os01 ~]# echo "www.$testedu.com"    #shell将$后的testedu识别为变量名,所以为空
www..com
[root@os01 ~]# echo "www.${test}edu.com"
www.mageedu.com



引用:

    弱引用: "", 其内部的变量引用会被替换为变量值;

     强引用:'',其变量的变量引用会保持原有字符;

    命令引用:`COMMAND`, $(COMMAND),引用命令的执行结果;

示例:

#弱引用替换变量
[root@os01 ~]# echo "$test"      
bird
#强引用保持原有字符
[root@os01 ~]# echo '$test'
$test
#命令引用:`COMMAND`, $(COMMAND),引用date命令的执行结果;
[root@os01 ~]# echo date
date
[root@os01 ~]# echo `date`
Tue 15 Sep 14:34:58 CST 2015
[root@os01 ~]# echo $(date)
Tue 15 Sep 14:35:07 CST 2015



声明为整型:

    declare -i name[=value]

    let name=value

示例:

#声明整数类型 a=5,在没有声明整数类型的情况下b=5其结果一样,这是因为bash为弱类型、无须事先声明,在使用变量的时候会进行隐式转行,b在计算的时候转换为数字5;

[root@os01 ~]# declare -i a=5
[root@os01 ~]# expr $a + 2
7
[root@os01 ~]# b=5                 
[root@os01 ~]# b=5           
[root@os01 ~]# expr $b + 2 
7


查看所有变量:set

示例:查看所有本地变量与特定的本地变量

[root@os01 ~]# set|less
ABRT_DEBUG_LOG=/dev/null
BASH=/bin/bash
BASHOPTS=checkwinsize:cmdhist:expand_aliases:extglob:extquote:force_fignore:histappend:interactive_comments:login_shell:progcomp:promptvars:sourcepath
BASH_ALIASES=()
BASH_ARGC=()
....
[root@os01 ~]# set|egrep "\btest\b"
test=mage
[root@os01 ~]# set|egrep "\b^a\b"


a=5

生命周期:

创建

销毁:

    自动销毁:shell进程终止;

    手动销毁:unset name

示例:unset手动销毁

[root@os01 ~]# set|egrep "\btest\b"
test=mage
[root@os01 ~]# unset test
[root@os01 ~]# set|egrep "\btest\b"
空



(2)环境变量

环境变量定义:

类似被“导出”的本地变量

export name[=value]

declare -x name[=value]

示例:定义环境变量,在子shell中仍旧生效,但是在logout以及切换用户后失效

[root@os01 ~]# export test=hello
[root@os01 ~]# echo $test
hello
[root@os01 ~]# bash
[root@os01 ~]# echo $test            
hello                                         #子shell内生效
[root@os01 ~]# su - user1
Last login: Tue Sep 15 15:06:13 CST 2015 on pts/1
[user1@os01 ~]$ echo $test
空                                            #切换用户生效
[user1@os01 ~]$ 
[root@os01 ~]# exit
logout
[root@os01 ~]# echo $test
空                                            #logout后失效
[root@os01 ~]#


查看所有环境变量:

env, printenv, export

示例:查看所有环境变量和test变量内容

[root@os01 ~]# env
XDG_SESSION_ID=2736
HOSTNAME=os01
TERM=linux
SHELL=/bin/bash
...
[root@os01 ~]# printenv 
XDG_SESSION_ID=2736
HOSTNAME=os01
TERM=linux
SHELL=/bin/bash
...
[root@os01 ~]# export
declare -x HISTCONTROL="ignoredups"
declare -x HISTSIZE="1000"
declare -x HOME="/root"
[root@os01 ~]# env|grep '\<test\>'             #查看test系统变量内容
test=hello



销毁:

unset name

示例:销毁test系统环境变量

[root@os01 ~]# export test=hello  
[root@os01 ~]# echo $test
hello
[root@os01 ~]# unset test
[root@os01 ~]# echo $test
空
[root@os01 ~]#



(3)局部变量

局部变量:某个函数执行过程;只在函数执行过程中生效;

示例:var1,var2变量只在函数执行过程中生效,为局部环境变量

[root@os01 ~]# cat a.sh 
#!/bin/bash
var1="hello"
fun_1() {
var2="word"
echo $var1 $var2
}
fun_1
[root@os01 ~]# ./a.sh 
hello word                         #var1,var2变量只在函数执行过程中生效,为局部环境变量
[root@os01 ~]# echo $var1
空
[root@os01 ~]# echo $var2
空                                    #函数体外不生效
[root@os01 ~]#



(4)位置参数变量

位置参数变量:

        在脚本中引用传递给脚本的参数;在函数中引用传递给函数的参数;特殊变量:$?, $*, $@, $#, $$

示例:

[root@os01 ~]# cat t.sh 
#!/bin/bash
echo \$0 is $0          显示脚本名
echo \$1 is $1          第一个参数值
echo \$2 is $2          第二个参数值
echo \$3 is $3          第三个参数值
echo \$\* is $*         所有参数值
echo \$\@ is $@         同上,所有参数值
echo \$\# is $#         参数的个数
echo \$\$ is $$         这个脚本执行的PID(process id)
echo \$\? is $?         执行结果返回状态值
[root@os01 ~]# ./t.sh a b c
$0 is ./t.sh 显示脚本名
$1 is a 第一个参数值
$2 is b 第二个参数值
$3 is c 第三个参数值
$* is a b c 所有参数值
$@ is a b c 同上,所有参数值
$# is 3 参数的个数
$$ is 31794 这个脚本执行的PID(process id)
$? is 0 执行结果返回状态值


命令状态

命令状态结果:

bash进程用于追踪执行的命令成功与否的状态:

0: 成功

1-255:失败

特殊变量:

$?:上一条命令的执行状态结果;


布尔型:

“真”:成功

“假”:失败

自定义脚本的状态结果:

exit [n]

注意:脚本中任何位置执行了exit命令即会终止当前shell进程;

示例:

#创建目录testdir,查看返回值
[root@os01 ~]# rm -fr testdir/
[root@os01 ~]# mkdir testdir  
[root@os01 ~]# echo $?
0                                    #成功返回值为0
[root@os01 ~]# mkdir testdir
mkdir: cannot create directory ‘testdir’: File exists
[root@os01 ~]# echo $?      
1                                    #失败返回值不为0
#自定义返回值为49
[root@os01 ~]# cat test.sh 
#!/bin/bash
a=hello
b=world
echo $a $b
exit 49                              #自定义返回值为49
[root@os01 ~]# ./test.sh 
hello world
[root@os01 ~]# echo $?
49


你可能感兴趣的:(linux,shell,bash)