shell编程概念

一、什么是Shell?

Shell是一个命令解释器,它在操作系统的最外层,负责直接与用户对话,把用户的输入解释给操作系统,并处理各种各样的操作系统的输出结果,输出到屏幕返回给用户。这种对话方式可以是交互的方式(从键盘输入命令,可以立即得到Shell的回应),或非交互(脚本的方式)。

二、 什么是Shell脚本?

当命令或语句不在命令行执行,而是通过一个程序文件执行时,该程序就被称为Shell脚本或Shell程序,Shell程序类似DOS系统下的批处理程序(*.bat)。用户可以在Shell脚本中敲入一系列的命令或命令语句。这些命令、变量和流程控制语句等有机的结合起来就形成了一个功能强大的Shell脚本。

三、Linux中有哪些脚本解释器?

   有dash和bash两种,但dash没有bash功能全面,所以通常使用bash。
   可以通过命令来查看系统中的脚本解释器:  ls  -l  /bin/*sh

在这里插入图片描述
重点:
脚本开头的第一行(如果不是第一行,#就是注释了),指定由哪一个解释器来执行脚本中的文件如:#!/bin/bash
“#!” 符号是指定一个文件类型的特殊标记,它告诉Linux系统这个文件执行的需要指定一个解释器。
“#!” 符号后跟的是一个路径名,这个路径名指明了解释器在系统中的位置。

四、Shell脚本的执行过程、执行方式详解

当Shell脚本运行时,它会先查找系统环境变量ENV,该变量指定了环境文件(加载顺序通常是/etc/profile、~ /.bash_profile、~/.bashrc、/etc/bashrc等),在加载了上述环境变量文件后,Shell就开始执行Shell脚本中的内容。(所以在开发的时候,有时候想定义的全局变量时,可以不在脚本定义,而在环境变量中定义)

Shell脚本是从上至下、从左至右依次执行每一行的命令及语句的,即执行完了一个命令后再执行下一个,如果在Shell脚本中遇到子脚本(即脚本嵌套)时,就会先执行子脚本的内容,完成后再返回父脚本继续执行父脚本内后续的命令及语句。

通常情况下,在执行Shell脚本时,会向系统内核请求启动一个新的进程,以便在该进程中执行脚本的命令及子Shell脚本,基本流程如图:

在这里插入图片描述
Shell脚本的执行通常可以采用以下几种方式:

1)bash script-name或sh script-name
这是当脚本文件本身没有可执行权限(即文件权限属性x位为-号)时常使用的方法,或者脚本文件开头没有指定解释器时需要使用的方法;

举例说明:

[root@localhost ~]# vim test.sh
echo 'this is a shell scripts!'
[root@localhost ~]# sh test.sh    //指定解释器sh执行。sh是bash的软连接。推荐用bash方式,防止后面版本升级后不一样。
this is a shell scripts!
[root@localhost ~]# bash test.sh  //指定解释器bash执行。
this is a shell scripts!

2)path/script-name或./script-name
指在当前路径下执行脚本(脚本需要有执行权限),需要将脚本文件的权限先改为可执行(即文件权限属性加x位),具体方法为chmod+x script-name。然后通过脚本绝对路径或相对路径就可以直接执行脚本了;

举例说明:

[root@localhost ~]# ./test.sh
-bash: ./test.sh: 权限不够
[root@localhost ~]# chmod u+x test.sh
[root@localhost ~]# ./test.sh
this is a shell scripts!

这种方法比较麻烦一些!每次编写完脚本都必须给脚本一个执行的权限,否则将会提示“权限不够”的错误。

3)source script-name或.script-name
这种方法通常是使用source或“.”(点号。点号后是空格)读入或加载指定的Shell脚本文件(如san.sh),然后,依次执行指定的Shell脚本文件san.sh中的所有语句。这些语句将在当前父Shell脚本father.sh进程中运行(其他几种模式都会启动新的进程执行子脚本)。因此,使用source或“.”可以将san.sh自身脚本中的变量值或函数等的返回值传递到当前父Shell脚本father.sh中使用。

举例说明:
重点:通常,当前运行的窗口是一个shell,运行脚本的是另一个shell。

[root@localhost ~]# echo 'user=`whoami`' > test2.sh
[root@localhost ~]# cat test2.sh 
user=`whoami`
[root@localhost ~]# sh test2.sh   //用sh或者bash执行,系统会启动新的进程执行子脚本,执行完就返回父shell,变量或函数无法保留。
[root@localhost ~]# echo $user    //所以,输出变量$user 是空

[root@localhost ~]# . test2.sh   //通过source或“.”加载执行过的脚本,系统不会新建进程执行子shell,都是在当前Shell中执行脚本,因此在脚本结束之后,脚本中的变量(包括函数)值在当前Shell中依然存在.
[root@localhost ~]# echo $user //因为执行 user=`whoami`时,变量$user被保留下来了,所以输出root
root

本人亲自尝试得出的结论有三点:

1.子Shell脚本会直接继承父Shell脚本的变量、函数(就好像是儿子随父亲姓,基因也会继承父亲的)等,反之则不可以;
2.如果希望反过来继承(就好像是让父亲随儿子姓,让父亲的基因也继承儿子的),就要用source或“.”在父Shell脚本中事先加载子Shell脚本;
3.通过source或“.”加载执行过的脚本,由于是在当前Shell中执行脚本,因此在脚本结束之后,脚本中的变量(包括函数)值在当前Shell中依然存在,而sh和bash执行脚本都会启动新的子Shell执行,执行完后退回到父Shell。因此,变量(包括函数)值等无法保留。在进行Shell脚本开发时,如果脚本中有引用或执行其他脚本的内容或配置文件的需求时,最好用“.”或source先加载该脚本或配置文件,处理完之后,再将它们加载到脚本的下面,就可以调用source加载的脚本及配置文件中的变量及函数等内容了。

4)sh<script-name或cat scripts-name|sh
同样适用于bash,不过这种用法不是很常见,但有时也可以有出奇制胜的效果,例如:不用循环语句来实现精简开机自启动服务的案例,就是通过将所有字符串拼接为命令的形式,然后经由管道交给bash操作;

举例说明:

[root@localhost ~]# ll test.sh
-rw-r--r--. 1 root root 32 826 03:09 test.sh
[root@localhost ~]# sh<test.sh
this is a shell scripts!
[root@localhost ~]# cat test.sh|bash
this is a shell scripts!

五、shell脚本开发的基本规范和习惯

1.脚本文件开头指定脚本解释器;

#/bin/sh或#!/bin/bash

2.脚本文件开头版本版权等信息:

#Date:          21:30  2013-07-20
#Author:        Created by Guomaoqiu
#Mail:         guomaoqiu@sina.com
#Function:      This scripts function is ......
#Shell Version: GNU bash, version 3.2.25(1)-release

提示:可配置vim编辑文件时自动加上以上信息,方法是修改~/.vimrc配置文件。

3.脚本文件中不用中文注释;

尽量用英文注释,防止本机或切换系统环境后中文乱码的困扰.

4.脚本文件以.sh为扩展名;

例如:script-name.sh

5.代码书写优秀习惯;

5.1成对内容的一次性写出来,防止遗漏。如

  {}[]''、``、""
 
5.2[]中括号两端要有空格,书写时即可留出空格[    ],然后再退格书写内容。

5.3流程控制语句一次性书写完,再添加内容,如:

#if语句格式一次性完成:

if 条件内容
	then
		内容
fi

#for循环格式一次性完:

for
	do
		内容
done

提示:while和until,case 等语句也是一样。

6.通过缩进让代码易读;(即该有空格的地方就要有空格)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值