关山难越,谁悲失路之人;萍水相逢,尽是他乡之客。
百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程教程 > 技术文章 > 正文

细说Shell脚本(一)

guanshanw 2023-08-22 02:49 31 浏览 0 评论

作为一个开发者,我们会经常用到shell脚本来解决问题,无论是后端开发工程师还是运维人员,都离不开shell的使用。但是我们对shell脚本大部分都是应用阶段,下面我们来详细地介绍一下shell脚本的来龙去脉。


一、解释Shell

定义:Shell是一个命令行解释器

作用:解释执行用户输入的命令及程序

二、Shell的在操作系统中的结构

位置:Shell存在于操作系统最外层,负责与用户直接对话

作用:把用户的输入解释给操作系统,并处理操作系统的输出结果,然后将结果输出到屏幕上


Shell在操作系统中的位置

三、解释Shell脚本

定义:当命令或程序语句通过一个程序文件来执行时,该程序就被称为Shell脚本

作用:用户可以在Shell脚本中敲入一系列的命令及命令语句组合。这些命令、变量和流程控制语句等有机地结合起来,就形成了一个功能强大的Shell脚本。

四、示例

清除Linux系统日志执行命令

cd /var/log
cat /dev/null > messages

通过执行上面的命令,我们就清除了linux系统日志

我们可以通过如下写成一个简单的Shell脚本,我们就先假设名字叫做test.sh

#! /bin/bash
cd /var/log
cat /dev/null > messages

我们将上面的内容写入test.sh后,test.sh就是一个Shell脚本了。

但是,执行这个脚本有相应的权限

显然,上面的这个脚本写得过于简单,不够严谨,下面我们来写一个相对较好的Shell脚本

#! /bin/bash
#日志文件所在目录
LOG_DIR=/var/log
#root用户的uid为0,在此声明是为了做限制(root用户才能执行)
ROOT_UID=0
#判断用户是否为root用户(如果用户id不等于0,也就是不是root用户)
if [ "$UID"-ne "$ROOT_UID" ]
then 
	#给出提示
	echo "only root to run this script."
	#退出
  exit 1
fi
#切换目录
cd $LOG_DIR || {
	#切换失败,则给出提示
  echo "change dir failed."
  #退出
  exit 2
}
#清除日志并返回结果
cat /dev/null > messages && {
  #给出成功提示
	echo "cleaned log success."
  #退出
  exit 0
}
#给出失败提示
echo "cleaned log failed."
#退出
exit 3

这样是不是看着就完美多了。

五、Shell脚本基本说明

Shell脚本语言是弱类型语言

Linux系统上的/bin/sh往往是指向/bin/bash的符号链接。但是,bash和sh还是有很多的不同之处: 1. bash扩展了一些命令和参数

  1. bash并不完全和sh兼容,它们有些行为并不一致,但在大多数企业运维的情况下区别不大,特殊场景可以使用bash替代sh

查看当前系统支持的shell命令:

cat /etc/shells

Linux系统中的主流Shell是bash

Shell脚本语言的优势在于处理偏操作系统底层的业务

对于一些常见的系统脚本,使用Shell开发会更简单、更快速

Linux下默认的Shell是bash,查看系统的默认Shell命令:

方式一:echo $SHELL

方式二:grep root /etc/passwd

六、Shell脚本结构说明

脚本开头

规范要求Shell脚本在第一行指定(解释器)来执行脚本,一般情况为:

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

#要求在255个字符以内

在执行bash脚本的时候,内核会根据“#!”后的解释器来确定该用哪个程序解释这个脚本中的内容

注意:这一行必须位于每个脚本顶端的第一行,如果不是第一行则为脚本注释行

sh为bash的软链接,大多数情况下,脚本的开头使用“#! /bin/bash”和“#! /bin/sh”是没有区别的,但更规范的写法是在脚本的开头使用“#! /bin/bash”

一般情况下,在安装Linux系统时会自动安装好bash软件,查看系统的bash版本的命令如下:

#linux的环境版本
cat /etc/redhat-release
#bash的版本
bash --version

检测系统是否存在漏洞的方法为:

env x='() { :; }; echo becareful' bash -c "echo this is a test"

如果输出中出现了becareful,则表示需要尽快升级bash

升级命令:

yum -y update bash
rpm -qa bash

CentOS和Red Hat Linux下默认的Shell均为bash。因此,在写Shell脚本的时候,脚本的开头即使不加“#! /bin/bash”,它也会交给bash解释。如果写脚本不希望使用系统默认的Shell解释,那么就必须要指定解释器了

在Shell脚本中,跟在#后面的内容表示注释

七、Shell脚本的执行

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

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

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

注意:设置Linux的crond任务时,最好能在定时任务脚本中重新定义系统环境变量,否则,一些系统环境变量将不会被加载

八、Shell脚本执行的几种方式

1.bash script-name或sh script-name

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

2.path/script-name或./script-name

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

3.source script-name或.script-name

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

source或“.”命令的功能是:在当前Shell中执行source或“.”加载并执行的相关脚本文件中的命令及语句,而不是产生一个子Shell来执行文件中的命令。注意“.”和后面的脚本名之间要有空格

4.sh<script-name或cat scripts-name|sh

通过将所有字符串拼接为命令的形式,然后经由管道交给bash操作的案例中经常看到这样的操作

通过source或“.”加载执行过的脚本,由于是在当前Shell中执行脚本,因此在脚本结束之后,脚本中的变量(包括函数)值在当前Shell中依然存在,而sh和bash执行脚本都会启动新的子Shell执行,执行完后退回到父Shell。因此,变量(包括函数)值等无法保留。在进行Shell脚本开发时,如果脚本中有引用或执行其他脚本的内容或配置文件的需求时,最好用“.”或source先加载该脚本或配置文件,处理完之后,再将它们加载到脚本的下面,就可以调用source加载的脚本及配置文件中的变量及函数等内容了。

九、Shell脚本基本规范

1.Shell脚本的第一行是指定脚本解释器

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

2.Shell脚本的开头要加版本、版权等信息

#Date: 2020-11-00

#Author: Created by xx

#Blog: http:/xx.blog.51cto.com

#Description: This scripts function is ...

#Version: 1.1

以上两点可修改“~/.vimrc”配置文件配置vim编辑文件时自动加上以上信息的功能

3.在Shell脚本中尽量不用中文(不限于注释)

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

4.Shell脚本的命名应以.sh为扩展名

script-name.sh

5.Shell脚本应存放在固定的路径下

/server/scripts

6.对的符号应尽量一次性写出来,然后退格在符号里增加内容,以防止遗漏

这些成对的符号包括:

{}、[]、''、``、""

中括号([])两端至少要有1个空格,因此,键入中括号时即可留出空格[ ],然后再退格键入中间的内容,并确保两端都至少有一个空格,即先键入一对中括号,然后退1格,输入两个空格,再退1格,双中括号([[]])的写法也是如此

7.于流程控制语句,应一次性将格式写完,再添加内容,通过缩进让代码更易读

if 条件
then 
	内容
fi
for 
do
  内容
done

while和until, case等语句也一样

8.对于常规变量的字符串定义变量值应加双引号,并且等号前后不能有空格,需要强引用的(指所见即所得的字符引用),则用单引号(' '),如果是命令的引用,则用反引号(` `)

MY_FILE="test.txt"

9.脚本中的单引号、双引号及反引号必须为英文状态下的符号,其实所有的Linux字符及符号都应该是英文状态下的符号


希望能对大家有所帮助,谢谢


相关推荐

七条简单命令让您玩转Git
七条简单命令让您玩转Git

凭借着出色的协作能力、快速部署效果与代码构建辅助作用,Git已经得到越来越多企业用户的青睐。除了用于开发商业及消费级应用之外,众多科学及政府机构也开始尝试使用这...

2023-10-07 12:14 guanshanw

基本完整的关于Git分支branch的操作
基本完整的关于Git分支branch的操作

Git使用背景项目中要用到dev或者其他分支开发完代码,需要将该分支合并到master的需求操作步骤下面以dev名称为lex为分支名为例来操作一遍客户端操作:...

2023-10-07 12:14 guanshanw

Git 进阶(合并与变基)
Git 进阶(合并与变基)

在Git中整合来自不同分支的修改主要有两种方法:合并(merge)以及变基(rebase)合并(merge)merge流程图merge的原理是找到这两个分...

2023-10-07 12:13 guanshanw

Git学习笔记 003 Git进阶功能 part5 合并(第一部分)

合并(merge)是很常用的操作。尤其是一个庞大的很多人参与开发的企业级应用。一般会设定一个主分支,和多个副分支。在副分支开发完成后,合并到主分支中。始终保持主分支是一个完整的,稳定的最新状态的分支。...

非标题党,三张图帮你理解git merge和git rebase的区别
非标题党,三张图帮你理解git merge和git rebase的区别

初始场景:基于正常的开发分支修改几个小bug,然后在合并到开发分支上。gitmergegitcheckoutfeaturegitmergeho...

2023-10-07 12:13 guanshanw

git 初次使用(01)
git 初次使用(01)

先从github上克隆代码下来:使用vscode克隆代码如下图,填写上github仓库地址:vscode有时候克隆代码速度比较慢,可以用命令行方式克隆gitc...

2023-10-07 12:12 guanshanw

Git 远程操作

4.Git远程操作命令说明gitremote远程版本库操作gitfetch从远程获取版本库gitpull下载远程代码并合并gitpush上传远程代码并合并4.1远程版本库操作gitre...

Git常用命令-总结
Git常用命令-总结

创建git用户$gitconfig--globaluser.name"YourName"$gitconfig--globaluser.em...

2023-10-07 12:12 guanshanw

git中删除从别人clone下来项目的git信息,并修改为自己的分支

如果你从别人的Git存储库中克隆了一个项目,并想要删除与该存储库相关的Git信息,并将其修改为你自己的分支,则可以执行以下步骤:使用gitclone命令克隆存储库:gitclone<u...

git系列-回滚和放弃本地修改

回滚历史提交就是reset的功能。这种情况是已经提交远程仓库,需要回滚到之前的提交。gitreset--hardcommitId//注:强制提交后,当前版本后面的提交版本将会删掉!gi...

GIT使用小技巧大全
GIT使用小技巧大全

在大型软件工程的开发过程中,版本控制是无法绕过去的;目前来说,最火的版本控制软件就是GIT了。早两年SVN比较火,不过被大神linus喷了几次后,就日落西山了,...

2023-10-07 12:11 guanshanw

git相关命令-上
git相关命令-上

这些命令都是看了文档后,个人觉得比较有用的一些,展示给大家。回到远程仓库的状态抛弃本地所有的修改,回到远程仓库的状态。gitfetch--all&...

2023-10-07 12:10 guanshanw

Git命令行接口:掌握Git的必备技能
Git命令行接口:掌握Git的必备技能

Git是一款强大的分布式版本控制工具,它支持命令行界面操作。熟练掌握Git命令行接口,是开发者使用Git的必备技能之一。在这篇文章中,我们将介绍Git命令行接口...

2023-10-07 12:10 guanshanw

Git命令详解
Git命令详解

相信各位小伙伴们应该都对git有一些了解,毕竟作为代码管理的神器,就算不是IT行业的小伙伴肯定也或多或少的听说过一些。今天就来和小伙伴们分享一下自己总结的常用命...

2023-10-07 12:10 guanshanw

工作7年收集到的git命令
工作7年收集到的git命令

概念git中的术语解释:仓库也叫版本库(repository)stage:暂存区,add后会存到暂存区,commit后提交到版本库git安装linux...

2023-10-07 12:10 guanshanw

取消回复欢迎 发表评论: