Linux入门小抄-part5-Shell编程基础(上)

一.Linux shell简介

1.1、Shell概述

Shell本身是一个用C语言编写的程序,它是用户使用Unix/Linux的桥梁,用户的大部分工作都是通过Shell完成的。

Shell既是一种命令语言,又是一种程序设计语言:

作为命令语言,它交互式地解释和执行用户输入的命令;

作为程序设计语言,它定义了各种变量和参数,并提供了许多在高级语言中才具有的控制结构,包括循环和分支。

Shell它虽然不是Unix/Linux系统内核的一部分,但它调用了系统核心的大部分功能来执行程序、建立文件并以并行的方式协调各个程序的运行。Shell是用户与内核进行交互操作的一种接口,目前最流行的Shell称为bash Shell(Bourne Again Shell)

Shell是一门编程语言(解释型的编程语言),即shell脚本(就是在用linux的shell命令编程),Shell脚本程序从脚本中一行一行读取并执行这些命令,相当于一个用户把脚本中的命令一行一行敲到Shell提示符下执行

Shell是一种脚本语言,那么,就必须有解释器来执行这些脚本

Unix/Linux上常见的Shell脚本解释器有bash、sh、csh、ksh等,习惯上把它们称作一种Shell。我们常说有多少种Shell,其实说的是Shell脚本解释器,可以通过cat /etc/shells命令查看系统中安装的shell,不同的shell可能支持的命令语法是不相同的

sh是Unix 标准默认的shell,由Steve Bourne开发,是Bourne Shell的缩写。

bash是Linux标准默认的shell,本教程也基于bash讲解。bash由Brian Fox和Chet Ramey共同完成,是Bourne Again Shell的缩写。

Shell本身支持的命令并不多,内部命令一共有40个,但是它可以调用其他的程序,每个程序就是一个命令,这使得Shell命令的数量可以无限扩展,其结果就是Shell的功能非常强大,完全能够胜任Linux的日常管理工作,如文本或字符串检索、文件的查找或创建、大规模软件的自动部署、更改系统设置、监控服务器性能、发送报警邮件、抓取网页内容、压缩文件等。

1.2、Shell基本格式

shell脚本的代码写在普通文本文件中,通常以.sh结尾,虽然不是强制要求,但希望大家最好这么做

我们先写一个hello.sh的亘古不变的"你好世界"

我们以.sh结尾.进入编辑器后,主要就写两行  #后面的是注释  

保存退出即可.

在这里,我们就写好了一个shell脚本,第一行是固定需要的,表明用哪一种shell解析器来执行我们的这个脚本程序。本质上,shell脚本里面的代码都是就是一些流程控制语句加一些特殊语法再加shell命令组成。其中,我们可以当做每一个命令就是shell编程当中的关键字。

1.3、Shell执行方式

1、sh方式或者bash方式

sh helloworld.sh    

bash helloworld.sh   ## 直接指定用系统默认的bash shell解释执行

2、source方式或者.方式

source命令也称为“点命令”,也就是一个点符号(.),是bash的内部命令。

功能:使Shell读入指定的Shell程序文件并依次执行文件中的所有语句

source命令通常用于重新执行刚修改的初始化文件,使之立即生效,而不必注销并重新登录。

注意:. 和脚本名称之间是有空格的

3、直接执行该脚本文件

可以有两种方式,不过这两种方式的执行,都需要该文件有执行权限

所以在执行之前,我们要更改他的执行权限  chmod 命令

为什么执行不了呢?  我们上面说过,shell脚本文件的第一行写的#!/bin/bash表示用哪一种shell解析器来解析执行我们的这个脚本程序,这句话只对自执行有效,对于使用sh helloworld.sh无效 .我们将这行注释删掉,就可以直接执行了.

1.4、Shell注释

单行注释:Shell脚本中以#开头的代码就是注释

多行注释:Shell脚本中也可以使用多行注释:

:<<!

echo "dd"     ## 这句话是注释,也就是说在 :<<!   注释语句    中间的都是注释

!

二、Shell基本语法

2.1、变量

2.1.1、系统变量

Linux Shell中的变量分为“系统变量”和“用户自定义变量”

系统变量可以通过set命令查看,用户环境变量可以通过env查看:

常用系统变量:$PWD    $SHELL     $USER    $HOME

 

2.1.2、自定义变量

语法

变量=值 (例如STR=abc)

等号两侧不能有空格

变量名称一般习惯为大写

使用变量: $STR

      

注意:

命令:A=xiao ming,定义变量时中间带有空格,那么一定要带引号,不然不能定义

命令:A='xiao ming',带了单引号则原样输出。表示引号中间的值是整体字符串

命令:A="xiao ming",带了双引号,表是字符串中运行出现引用变量和转移字符等

上面说了三点,貌似什么也没看出来.别急,在引号当中要引用变量的时候,单引号和双引号的区别就明显啦:

如果是单引号,则引号当中的任何东西都当做字符串,即特殊字符会被脱意

如果是双引号,那么$ABC能打印出变量的值

单引号和双引号总结:

单引号:

1、单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的

2、单引号字串中不能出现单引号(对单引号使用转义符后也不行)

双引号:

1、双引号里可以有变量

2、双引号里可以出现转义字符

我们再看一下下面这个案例:遇到下面的情况,我们要用{}来讲变量括起来

变量的高级用法

撤销变量:unset A

声明静态变量:readonly A= 'abc'     特点是这种变量是只读的,不能unset

现在写两个脚本,在a.sh中调用b.sh执行,那我们想知道a脚本能不能获取到b脚本的变量,b脚本能不能获取到a脚本的变量?

#!/bin/bash

A="A in a.sh"

echo $A

echo $B

/root/bin/b.sh

#!/bin/bash

B="B in b.sh"

echo $A

echo $B

上面的是a.sh ,下面是b.sh..我们来执行bash a.sh

在a.sh中只打印出了变量A的值,这个好理解,因为shell是顺序解析执行的,在打印变量B的时候,就算它能获取到b.sh当中的变量,它也还没执行,所以,肯定获取不到

那再看b.sh打印出来的结果:可以发现虽然a.sh当中的语句执行完了再调用b.sh来执行,但是b.sh脚本依然也没法获取到a.sh的变量

那怎么解决?

使用export关键字

export A="A in a.sh"

意味着把变量提升为当前shell进程中的全局环境变量,可供其他子shell程序使用,

A变量就成了a.sh脚本所在bash进程的全局变量,该进程的所有子进程都能访问到变量A

另外一种使用方式:

如果在a.sh脚本中用如下方式调用b.sh:. /root/bin/b.sh    ## 注意:重点关注最前面那个“.”号  或者  source /root/bin/b.sh

 

用上述两种方式意味着:b.sh就在a.sh所在的bash进程空间中运行

总结:

1、a.sh中直接调用b.sh,会让b.sh在A所在的bash进程的“子进程”空间中执行

2、而子进程空间只能访问父进程中用export定义的变量

3、一个shell进程无法将自己定义的变量提升到父进程空间中去

4、source或者“.”号执行脚本时,会让脚本在调用者所在的shell进程空间中执行

 

反引号赋值

a=`ls -l /root/bin`  ##反引号,运行里面的命令,并把结果返回给变量a

另外一种写法:

a=$(ls -l /root/bin)

 

 

变量小技巧

形式

说明

${var}

变量本来的值

${var:-word}

如果变量 var 为空或已被删除(unset),那么返回 word,但不改变 var 的值

${var:+word}

如果变量 var 被定义,那么返回word,但不改变 var 的值

${var:=word}

如果变量 var 为空或已被删除(unset),那么返回 word,并将 var 的值设置为 word

${var:?message}

如果变量 var 为空或已被删除(unset),那么将消息 message 送到标准错误输出,可以用来检测变量 var 是否可以被正常赋值。

若此替换出现在Shell脚本中,那么脚本将停止运行

2.1.3、特殊变量 

$?  表示上一个命令退出的状态码   0

$$  表示当前进程编号

$0 表示当前脚本名称

$n 表示n位置的输入参数(n代表数字,n>=1)

$# 表示参数的个数,常用于循环

$*和$@ 都表示参数列表 

[root@hadoop02 bin]# vi d.sh

#!/bin/bash

echo "test var"

echo $$

echo $0

echo $1

echo $2

echo $#

echo $*

echo $@

echo $?

 注:$*与$@区别

$* 和 $@ 都表示传递给函数或脚本的所有参数

 

不被双引号" "包含时  ====   $* 和 $@ 都以$1  $2  … $n 的形式组成参数列表

 

当它们被双引号" "包含时  ====

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

"$@" 会将各个参数分开,以"$1" "$2" … "$n" 的形式组成一个参数列表

猜你喜欢

转载自blog.csdn.net/XiaodunLP/article/details/83795264