Shel脚本-初步入门之《06》
Shel脚本-初步入门-06 Shell 脚本的建立和执行
6、Shell 脚本的建立和执行
6.1 Shell脚本的建立
在
Linux
系统中,Shell
脚本(bash Shell
程序)通常是在编辑器vi/vim
中编写的。推荐使用vim
编辑器来编写。
事先做一个别名
alias vi='vim'
,使其永久生效,方法如下:
echo "alias vi='vim'" >>/etc/profile
tail -1 /etc/profile
source /etc/profile
alias
1. 脚本开头(第一行)
一个规范的
Shell
脚本在第一行会指出由哪个程序(解释器)来执行脚本中的内容,这一行内容在Linux bash
的编程一般为:
#!/bin/bash
or
#!/bin/sh # 255 个字符以内
注意:这一行必须位于每个脚本顶端的第一行,如果不是第一行则为脚本注释行,例如:
cat mine.sh
2. bash 与 sh 的区别
早期的
bash
与sh
稍有不同,它还包含了csh
和ksh
的特色,但大多数脚本都可以不加修改地在sh
上 运行,比如:
ll /bin/sh
ll /bin/bash
提示:
sh
为bash
的软连接,大多数情况下,脚本的开头使用#!/bin/bash
和#!/bin/sh
是没有区别的,但更规范的写法是在脚本的开头使用#!/bin/bash
。
一般情况下,在安装
Linux
系统时会自动安装好bash
软件,查看系统的bash
版本的命令如下:
cat /etc/redhat-release
bash --version
检测系统是否存在漏洞:
env x='() { :;}; echo be careful' bash -c "echo this is a test"
如果返回如下两行,则表示需要尽快升级
bash
了:
be careful
this is a test
升级方法为:
yum -y update bash
rpm -qa bash
提示:如果没有输出
be careful
,则不需要升级。
下面是
Linux
中常用脚本开头的写法:
1 #!/bin/sh
2 #!/bin/bash
3 #!/usr/bin/awk
4 #!/bin/sed
5 #!/usr/bin/tcl
6 #!/usr/bin/expect # expect 解决交互式的语言开头解释器
7 #!/usr/bin/perl # Perl 语言解释器
8 #!/usr/bin/env python # Python 语言解释器
3. 脚本注释
在
Shell
脚本中,跟在#
后面的内容表示注释,用来对脚本进行注释说明,注释部分不会被当作程序来执行,仅仅是给开发者和使用者看的,系统解释器是看不到的,更不会执行。提示:注释尽量不要用中文,在脚本中最好也不要有中文。
6.2 Shell脚本的执行
当
Shell
脚本运行时,它会先查找系统环境变量ENV
,该变量指定了环境变量文件(加载顺序通常是/etc/profile
、~/.bash_profile
、~/.bashrc
、/etc/bashrc
等),在加载了上述环境变量文件后,Shell
就开始执行Shell
脚本中的内容。
Shell
脚本是从上至下、从左至右执行每一行的命令及语句的,即执行完了一个命令后再执行下一个,如果在Shell
脚本中遇到子脚本(即脚本嵌套)时,就会先执行子脚本的内容,完成后再返回父脚本继续执行父脚本内后续的命令及语句通常情况下,在执行
Shell
脚本时,会向系统内核请求启动一个新的进程,以便在改进程中执行脚本的命令及子Shell
脚本特殊技巧:设置
Linux
的crond
任务时,最好能在定时任务脚本中重新定义系统环境变量,否则,一些系统环境变量将不会被加载。
Shell
脚本的执行通常可以采用以下几种方式:
- 1)
bash/sh script-name
:这是当脚本文件本身没有可执行权限时常使用的方法,或者脚本文件开头没有指定解释器时需要使用的方法。- 2)
path/script-name
或者./script-name
:指在当前路径下执行脚本(脚本需要有执行权限)方法为:chmod +x script-name
- 3)
source script-name
或者. script-name
:这种方法通常使用source
或.
(点号)读入或加载指定的Shell
脚本文件,然后,依次执行指定的Shell
脚本文件中的所有语句。这些语句将在当前父Shell
脚本father.sh
进程中运行(其他几种模式都会启动新的进程执行子脚本)。因此,使用source
或.
(点号)可以将指定的Shell
脚本文件中的变量值或函数等的返回值传递到当前父Shell
脚本father.sh
中使用。- 4)
sh<script-name
或cat script-name | sh
:同样适用于bash
,不过这种用法不是很常见,但有时也可以有出奇制胜的效果。
范例1:创建模拟脚本 mine.sh
,并输入如下内容:
cat mine.sh
使用第 1 种方法实践,命令如下:
cat mine.sh
sh mine.sh
bash mine.sh
使用第 2 种方法实践,命令如下:
ll mine.sh
./mine.sh
虽然没有权限的
mine.sh
脚本不能直接被执行,但是可以用source
或.
(点号)来执行,如下:
ll mine.sh
. mine.sh
source mine.sh
提示:
source
或.
(点号)的功能相同,都是读入脚本并执行脚本。
给
mine.sh
添加可执行权限,命令如下:
ll mine.sh
chmod +x mine.sh
!ll
./mine.sh
可以看到,给
mine.sh
加完可执行权限后就能执行了,这种方法在使用前每次都需要给定执行权限,但容易忘记。
使用第 3 种方法实践时,会将
source
或.
执行的脚本中的变量值传递到当前的Shell
中,如下:
echo 'userdir=`pwd`' >mine.sh
cat mine.sh
sh mine.sh
echo $userdir
通过
sh/bash
命令执行过脚本,变量值不会赋值给当前Shell
窗口,使用source
或.
执行,结果如下:
echo $userdir
source mine.sh
!echo
结论: 通过
source
或.
加载执行过的脚本,由于是在当前Shell
中执行脚本,因此在脚本结束后,脚本中的变量(包括函数)值在当前Shell
中依然存在,而sh
和bash
执行脚本都会启动新的子Shell
执行,执行完后退回到父Shell
。因此,变量(包含函数)值等无法保留。
使用第 4 种方法实践,命令如下:
chmod -x mine.sh
ll mine.sh
echo "echo 'I love linux.'" >mine.sh
cat mine.sh
sh <mine.sh
cat mine.sh|bash
6.3 Shell脚本开发的基本规范及习惯
Shell
脚本的开发规范及习惯非常重要,虽然这些规范不是必须遵守的但有了好的规范和习惯,可以大大提升开发效率,并能在后期降低对脚本的维护成本。
- 1)
Shell
脚本的第一行是指定脚本解释器,通常为
#!/bin/bash
or
#!/bin/sh
- 2)
Shell
脚本的开头会加版本、版权等信息
# File Name: /server/scripts/backup_rsync.sh
# Version: V1.0
# Author: Mine
# Organization: www.cnblogs.com/wjcLinux/
# Created Time : 2019-05-10 16:24:08
# Description: deploy the rsync service
说明:以上两点在
Linux
系统场景中不是必需的,只属于优秀规范和习惯,后面有自动加载此内容的方法。(可以修改~/.vimrc
配置文件配置vim
编辑文件时自动加上以上信息的功能。)
- 3)在
Shell
脚本中尽量不用中文(不限于注释)。尽量用英文注释,防止本机或切换系统环境后中文乱码的困扰,若非要加中文,请根据自身的客户端对系统进行字符集调整,如:export LANG="zh_CN.UTF-8"
,并在脚本中重新定义字符集设置,和系统保持一致。- 4)
Shell
脚本的命名应以.sh
为扩展名。例如:script-name.sh
- 5)
Shell
脚本应存放在固定的路径下。例如:/server/scripts
以下则是
Shell
脚本代码书写的良好习惯。
- 1)成对的符号应尽量一次性写出来,然后退格在符号里增加内容,以防止遗漏,如:
{ }、[ ]、" "、' ' 、` `、( )
- 2)中括号
[ ]
两端至少有 1 个空格,因此,键入中括号时即可留出空格,然后在退格键入中间的内容,并确保两端都至少有一个空格,即先键入一对中括号,然后退 1 格,输入两个空格,在退 1 格,双中括号[[ ]]
的写法也是如此。- 3)对于流程控制语句,应一次性将格式写完,再添加内容。比如:
一次性完成
if
语句的格式, 应为:
if 条件内容
then
内容
fi
一次性完成
for
循环语句的格式,应为:
for
do
内容
done
提示:
while
和until
,case
等语句也是一样的。
- 4)通过缩进让代码更易读,比如
if 条件内容
then
内容
fi
- 5)对于常规变量的字符串定义变量值应加双引号,并且等号前后不能有空格,需要强引用的(指所见即所得的字符引用),则用单引号(' '),如果是命令的引用,则用反引号( ` ` ),例如:
TEST_FILE="test.txt"
- 6)脚本中的单引号、双引号及反引号必须为英文状态下的符号,其实所有的
Linux
字符及符号都应该是英文状态下的符号,这点需要特别注意。
【本文图片下载地址】【003-初步入门之《06》】点我快速打开分享(若异常,请私信,万分感谢) 【提取码:h4c3 】
今天你学习了吗?若有疑问,请留言、私信或加QQ群:647033350,大家一起进步吧!
Shel脚本-初步入门之《06》的更多相关文章
- Shel脚本-初步入门之《03》
Shel脚本-初步入门-Shell 脚本在 Linux 运维工作中的地位 3.Shell 脚本在 Linux 运维工作中的地位 Shell 脚本语言很适合用于处理纯文本类型的数据,而 Linux 系统 ...
- Shel脚本-初步入门之《01》
Shel脚本-初步入门-什么是 Shell 1.什么是 Shell Shell 是一个命令解释器,它的作用是解释执行用户输入的命令及程序等.Shell 存在于操作系统的最外层,负责与用户直接对话,把用 ...
- Shel脚本-初步入门之《02》
Shel脚本-初步入门-什么是 Shell 脚本 2.什么是 Shell脚本 当命令或程序语句不在命令行下执行,而是通过一个程序文件来执行时,改程序就被称为 Shell 脚本.如果在 Shell 脚本 ...
- Shel脚本-初步入门之《04》
Shel脚本-初步入门-04 脚本语言的种类 4.脚本语言的种类 4.1 Shell 脚本语言的种类 Shell 脚本语言是弱类型语言(无须定义变量的类型即可使用),在 Unix/Linux 中主要有 ...
- Shel脚本-初步入门之《05》
Shel脚本-初步入门-05 常用操作系统默认的 Shell 5.常用操作系统默认的 Shell 通过以下两种方法可以查看 CentOS Linux 系统默认的 Shell 方法1: echo $SH ...
- [拾 得] 一枚迷人的贝壳 SHELL / Linux | shell 脚本初步入门
坚持知识分享,该文章由Alopex编著, 转载请注明源地址: http://www.cnblogs.com/alopex/ 索引: 什么是shell shell的分类 shell脚本的执行方式 ...
- Shell编程-01-Shell脚本初步入门
目录 什么是Shell 什么是Shell脚本 Shell脚本语言的种类 常用操作系统默认Shell Shell 脚本的建立和执行 脚本规范 什么是Shell 简单来说Shell其实就是一个命令 ...
- shell脚本从入门到精通(初级)之入门篇
写在开头 本文是阅读<Linux命令行与shell脚本编程大全>时的一些笔记,主要是shell脚本的一些基本语法, 还有很多细节和高级内容没有写到. 笔者也是shell script菜鸟, ...
- (五)Lua脚本语言入门
---恢复内容开始--- 写完这篇Lua脚本语言入门,自己就要尝试去用Lua脚本语言写esp8266了,,自己现在挺心急的,因为朋友使用esp8266本来说自己帮忙写好程序的,但是用的单片机不一样自己 ...
随机推荐
- Linux下使用 github+hexo 搭建个人博客04-next主题优化
上篇我们说了 hexo 的优化,针对的站点的优化. 本篇讲解 next 主题的优化,包括:使用语言.前端页面显示宽度.菜单.侧栏.头像.添加或取消动画效果.打赏功能等等. 让页面排版更符合我们所要的功 ...
- 通过存储过程(SP)实现SQL Server链接服务器(LinkServer)的添加
1. 背景 当系统的微服务化做的不是很高的时候,部分功能要通过DB LinkServer 来实现跨 Server 查询,当然,有时候BI抽数据.DBA数据库维护可能也会创建LinkServer. 特别 ...
- android 完全区分double-tap 与 singal-tap 的方法
需求:viewpager显示图片,需要在双击时对图片进行缩放,单击时在屏幕下方弹出popwindow,由于android的双击本质就是两次单击,但是又不想在双击时触发单击时的动作,所以就在网上各种搜解 ...
- ARM-Linux中断系统【转】
转自:https://www.cnblogs.com/arnoldlu/p/7406441.html 1.前言 了解Linux中断子系统,同时也需要了解ARM体系结构中断处理流程:在熟悉整个软硬件架构 ...
- RabbitMQ学习笔记(七、RabbitMQ实战)
目录: 削峰 分布式事务 削峰: 利用RabbitMQ队列消费特性避免峰值下的DB访问,缓解连接压力,在DB释放连接后再去消息数据. 分布式事务: )XA协议:它是一个分布式事务协议,由事务管理器和资 ...
- acwing 471. 棋盘 解题记录
题解地址 https://www.acwing.com/problem/content/description/473/ 有一个m×m的棋盘,棋盘上每一个格子可能是红色.黄色或没有任何颜色的. 你现 ...
- HDL的三种描述方式
结构化描述 结构化描述方式是最原始的描述方式,是抽象级别最低的描述方式,但同时也是最接近于实际的硬件结构的描述方式.结构化的描述方式,思路就像在面包板上搭建数字电路一样,唯一的不同点就是我们通过HDL ...
- 用vbs和ADSI管理Windows账户
ADSI (Active Directory Services Interface)是Microsoft新推出的一项技术,它统一了许多底层服务的编程接口,程序员可以使用一致的对象技术来访问这些底层服务 ...
- Spring Cloud Zuul 那些你不知道的功能点
本文摘自于 <Spring Cloud微服务 入门 实战与进阶> 一书. 1. /routes 端点 当@EnableZuulProxy与Spring Boot Actuator配合使用时 ...
- ASP.NET Core 模型验证的一个小小坑
今天在我们的一个项目中遇到一个 asp.net core 模型验证(model validation)的小问题.当模型属性的类型是 bool ,而提交上来的该属性值是 null ,asp.net co ...