一、Shell概述
什么是Shell
解释Shell脚本名词之前,我们先来说下什么是Shell?
Shell是一个命令解释器,它在操作系统的最底层,负责直接与用户对话,把用户的输入解释给操作系统,并处理各种各样的操作系统的输出结果,输出到屏幕返回给用户。这种对话方式可以是交互的方式(从键盘输入命令,可以立即得到shell的回应),或非交互(脚本)的方式。
命令行解释器:使用户得以与内核进行沟通的“翻译官”
下面图中黄色部分就是命令解释器shell。
提示:Shell在英文中的意思是贝壳,从上图我们可以看出,命令解释器shell就像一个贝壳一样包住了系统核心。
解释:
用户下达指令,shell把用户的指令翻译成`系统内核`能识别的二进制数,然后传达给系统内核,系统内核会把指令进行查看分析,然后下达“进程调度”和“资源分配”指令给CPU,让CPU去执行,然后由计算机硬件来显示结果。
什么是shell脚本
Linux Shell脚本 :实现某种功能的,有执行权限的文本文件
内核的作用:资源分配和进程调度
命令或语句不在命令行执行,而是通过一个程序文件执行时,该程序就被称为shell脚本或Shell程序,shell程序很类似DOS系统下的批处理程序(*.bat)。用户可以在shell脚本中敲入一系列的命令或命令语句。这些命令、变量和流程控制语句等有机的结合起来就形成了一个功能强大的shell脚本。
Windows下利用批处理程序bat开发的备份网站及数据库的脚本
@echo off
set date=%date:~,%-%date:~,%-%date:~,%
mysqldump -uroot -poldboy -A -B > D:\bak\"%date%".sql
rar.exe a -k -r -s -m1 D:\bak\"%date%".sql.rar D:\bak\"%date%".sql
del D:\bak\*.sql
rar.exe a -k -r -s -m1 D:\bak\"%date%"htdocs.rar D:\work\PHPnow\htdocs
范例1:清除.var/log下messages日志文件的简单命令脚本
#把所有命令放在一个文件里堆积起来就形成了脚本,下面就是一个最简单的命令堆积形成的shell脚本。
#必须使用root身份来运行这个脚本
#清除日志脚本,版本1
cd /var/log
cat /dev/null > messages
echo "Logs cleaned up."
#提示:/var/log/messages是系统的日志文件
看完这个脚本有什么想法?
)不是root执行不了 )没有流程控制,就是没有逻辑性
范例2:包含命令、变量和流程控制语句的清除/var/log下messages日志文件的shell脚本
#!/bin/bash
#清除日志脚本,版本2
LOG_DIR=/var/log
ROOT_UID= #$UID=0的时候,用户才具有root用户的权限
#要使用root用户来运行.
if [ "$UID" -ne "$ROOT_UID" ]
then
echo "Must be root to run this scripts."
exit
fi
cd $LOG_DIR || {
echo"Cannot change to necessary directory." >&
exit
} cat /dev/null > messages && echo "Logs cleaned up."
exit
#退出之前返回0表示成功,返回1表示失败
扩展:
清除日志的三种方法:
[root@Web ~]# echo >test.log
[root@Web ~]# >test.log
[root@Web ~]# cat /dev/null >test.log
应用场景:保留文件,清空内容
脚本在执行时会启动一个子shell进程;
1.命令行中启动的脚本会继承当前shell环境变量;
2.系统自动执行的脚本(非命令行启动)就需要自我定义需要各环境变量;
编写脚本
1.指定脚本的执行环境 #!/bin/bash
2.注释信息
3.脚本的功能体
进程和shell的关系
1.在每个进程看来,当前主机上只存在内核和当前进程,不知道别的进程存在
2.进程是程序的副本,进程是程序执行实例
3.进程可同名,进程号不同就是不同的进程
4.进程是程序的副本,进程是程序执行示例
5.多个用户同时登录shell,每个Shell都会有所不同,彼此之间各不相干
6.允许同一个用户登录多次,每个Shell都会有所不同,彼此之间各不相干
7.同一个用户在不同地方登录的Shell都会不同,都对应不同的Shell进程
8.bash自身是一个外部程序,但启动以后会带有内部命令
9.父Shell的设定对于子Shell是无效的,所之亦然。
10.shell之间可以交互打开
shell脚本与perl,php,python语言的差别?
Shell的优势在于处理操作系统底层的业务(大量的命令为它做支撑,例如,grep,sed,awk)。
一键安装,报警脚本,常规的业务应用,shell开发更简单快速。
php,python优势在于开发运维工具,web界面的管理工具
Shell脚本很擅长处理纯文本类型的数据,而linux中几乎所有的配置文件、日志文件(如nfs,rsync,httpd,nginx,lvs等)都是纯文本类型的文本。因此,如果学好Shell脚本语言,就可以利用它Linux系统中发挥巨大的作用。
Linux系统支持的Shell
类型 说明
bsh:Bourne Shell 70年代中期诞生于贝尔实验室,脚本编程功能较强
csh 80年代早期诞生于加利福尼亚大学,使用C语言风格,命令行交互方便
ksh:Korn Shell 兼容Bsh的语法和C语法的交互特性
bash:Bourne-Again Shell bsh的升级版,吸取了ksh的一些特点,是大多数Linux的默认Shell程序 zsh 兼备各种Shell程序的优点,交互式操作效率更高
Shell脚本语言是弱类型语言,较为通用的shell有标准的Bourne shell (sh)和 C shell (csh)。其中 Bourne shell (sh)。其中 Bourne shell (sh)已经被bash shell取代。
当前的Linux主机支持哪些Shell?
#cat /etc/shells
/bin/sh //多数Unix默认的Shell
/bin/bash //多数Linux默认使用的Shell
/sbin/nologin //非登录Shell
/bin/tcsh
/bin/csh
/bin/csh
在RHEL系统中,实际上sh是bash的符号链接
CentOS Linux系统默认的shell是():
[root@Web ~]# echo $SHELL
/bin/bash
[root@Web ~]# grep root /etc/passwd
[root@Web ~]# grep root /etc/passwd
root:x:::root:/root:/bin/bash
Bash的基本特性
Tab键补全、快捷键
命令历史
命令别名
标准输入输出
重定向
管道操作
Tab键补全
命令补全 搜索PATH环境变量所指定的每个路径下以我们给出的字符串 开头的可执行文件,如果多于一个,两次tab,可以给出列表;否则将直接补全;
路径补全 搜索我们给出的起始路径下的每个文件名,并试图补全
快捷键
快捷键 注释
Ctrl+a 跳到命令行首
Ctrl+e 跳到命令行尾
Ctrl+u 删除光标至命令行首的内容
Ctrl+k 删除光标至命令行尾的内容
Ctrl+l 清屏
命令历史
默认记录1000条最近执行过的命令
存放位置:~/.bash_history
环境变量 注释
PATH 命令搜索路径
HISTSIZE 命令历史缓冲区大小
命令历史:history
参数选项 注释
-c 清空命令历史
-d OFFSET [n] 删除指定位置的命令
-w 保存命令历史至历史文件中
命令历史的使用技巧:
参数选项 注释
!n 执行命令历史中的第n条命令
!-n 执行命令历史中的倒数第n条命令;
!! 执行上一条命令;
!string 执行命令历史中最近一个以指定字符串开头的命令
!$ 引用前一个命令的最后一个参数
Esc, .
Alt+.
命令别名
语法:
alias CMDALIAS='COMMAND [options] [arguments]'
有效范围
在shell中定义的别名仅在当前shell生命周期中有效
别名的有效范围 仅为当前shell进程
相关操作
相关操作 注释
aliase 列出已定义的命令别名
unaliase 别名 删除指定的命令别名
unaliase -a 清空所有别名
alias 别名='实际命令' 定义新的命令别名
如何让定义的别名命令生效?
vim ~/.bashrc 只对某个用户生效
vim /etc/bashrc 对所有用户生效
标准输入输出
1.标准输入:从该设备接收用户输入的数据
2.标准输出:从该设备向用户输出的数据
3.标准错误:通过该设备报告执行中的出错信息
类型 设备文件 文件描述号 默认设备
标准输入 /dev/stdin 键盘
标准输出 /dev/stdout 显示器
标准错误 /dev/stderr 显示器
重定向
重定向:改变标准输入/输出/错误输出的方向
set -C 禁止对已经存在文件使用覆盖重定向
强制覆盖输出,则使用 >|
set +C 关闭上述功能
类型
类型 操作符 用途
重定向输入 < 将文本输入来源由键盘改为指定的文件
重定向输出 > 将命令行的正常执行输出保存到文件,而不是直接显示在屏幕上
>> 与>类似,但操作是追加而不是覆盖
重定向错误 > 将命令行的执行错误信息保存到文件,而不是直接显示在屏幕上
>> 与2>类似,但操作是追加而不是覆盖
混合重定向(重定向正确和错误输出信息) &> 相当于>和2>,覆盖到同一个文件
&>> 相当于>和2>>,追加到同一个文件
管道
管道:前一个命令的输出,作为后一个命令的输入
管道操作符”|“
cmd1 | cmd2 [...|cmdn] 将cmd1的输出结果,作为cmd2的输入
例如:
#pgrep -l "." | wc -l————统计运行的进程数
#ifconfig | grep "HWaddr"————查看本机的MAC地址信息
shell脚本的建立和执行
shell脚本(bash shell程序)通常是在编辑器(如vi/vim)中编写,由Unix/Linux命令、bash shell命令、程序结构控制语句和注释等内容组成。
脚本开头(第一行)
一个规范的shell脚本第一行会指出由哪个程序(解释器)来执行脚本中的内容,在linux bash编程中一般为:
#!/bin/bash
或
#!/bin/sh
“#!”又称为幻数,在执行bash脚本的时候,内核会根据它来确定该用哪个程序来解释脚本中的内容。这一行必须在脚本顶端的第一行,如果不是则为注释。
sh和bash的区别:
[root@Web ~]# ls -l /bin/sh
lrwxrwxrwx. root root 9月 /bin/sh -> bash
[root@Web ~]# ll /bin/sh
lrwxrwxrwx. root root 9月 /bin/sh -> bash
提示:sh为bash的软链接,这里推荐用标准写法#!/bin/bash
下面是linux常用脚本语言开头的编码写法,不同语言脚本的开头一般都要加上如相应语言的开头标识内容
#!/bin/sh
#!/bin/bash
#!/usr/bin/awk
#!/bin/sed
#!/usr/bin/tcl
#!/usr/bin/expect
#!/usr/bin/perl
#!/usr/bin/env python
Centos和RedHat Linux下默认的Shell均为bash。因此,在写shell脚本的时候,我们的脚本的开头也可以不加#!/bin/bash。但如果当前的shell非你默认的shell时,比如tcsh,那么就必须要写#!了。否则脚本文件就只能执行命令的集合,不能够使用shell内建的指令了,建议读者养成习惯,不管什么脚本最好都加上开头语言标识。
如果脚本的开头不指定解释器,那么,就要用对应的解释器来执行脚本。例如:
bash test.sh
python test.py
脚本注释
在shell脚本中,跟在(#)井号后面的内容表示注释,用来对脚本进行注释说明,注释部分不会被当作程序执行,仅仅是给人看的,系统解释器看不到的,注释可自成一行,也可以跟在脚本命令后面与命令在同一行。开发脚步时,如果没有注释,其他人就很难理解脚本究竟在做什么,时间长了自己也会忘记。因此,我们要尽量养成对所做的工作(脚本等)书写注释的习惯,不光是方便别人,也方便自己,否则,写完一个脚本后也许几天后就记不起脚本的用途了,再重新阅读也会浪费很多宝贵时间。对于团队的协作也不利。
Shell脚本的执行
当shell脚本以非交互式的方式运行时,它会先查找环境变量ENV,该变量指定了一个环境文件(通常是.bashrc),然后从该环境变量文件开始执行,当读取了ENV文件后,SHELL才开始执行shell脚本中的内容。
Shell脚本的执行通常可以采用一下三种方式:
bash script-name 或sh script-name(推荐使用)
path/script-name或./script-name(当前路径下执行脚本)
source script-name或. script-name #注意”.”点号
执行说明:
1.第一种方法是当脚本文件本身没有可执行权限(即文件x位为-号)时常使用的方法,这里推荐使用bash执行,或者文件开头没有指定解释器(推荐的方法)
2.第二种方法需要先将脚本文件的权限改成可执行文件(即文件加x位),具体方法:chmod u+x script-name或chmod 755 script-name。
然后通过脚本路径就可以直接执行脚本了。
在生产环境中,不少读者在写完shell脚本后,由于疏忽忘记给予该脚本文件执行权限,就直接应用了,结果导致脚本没有按自己的意愿手动或定时执行。
避免的方法是用第一种方法替代第二种。
3.第三种方法是使用source或者”.”点号读入或加载指定的shell脚本文件(如san.sh),然后依次执行指定shell脚本文件san.sh中的所有语句。这些语句将作为当前父shell脚本father.sh进程的一部分运行。因此,使用source或者”.”点号可以将san.sh自身脚本中的变量的值或函数等的返回值传递到当前的父shell脚本father.sh中使用。这是第三种方法和前两种的最大区别。也是值得读者注意的地方。
Source或者'.'点号命令的功能是在当前shell中执行source或者'.'点号加载并执行的相关脚本文件中的命令及语句,而不是产生一个子shell来执行命令文件中的命令
下面我们举例说明
[zgy@Web ~]$ cat >test.sh #编辑test.sh脚本文件 echo 'I am zgy' echo 'I am zgy'
输入"echo 'I am oldboy'"内容后按回车,然后在按ctrl+d组合键即可结束编辑。此操作作为特殊编辑方法,作为cat用法的扩展提及(在使用中去记忆是个好习惯)。
[zgy@Web ~]$ cat test.sh echo 'I am zgy' [zgy@Web ~]$ sh test.sh #使用第一种方式的sh命令执行test.sh脚本文件 I am zgy [zgy@Web ~]$ bash test.sh #使用第一种方式的bash命令执行test.sh脚本命令 I am zgy
我们使用第一种方法,发现均可以执行并得到预期的结果。
zgy@Web ~]$ ls -l test.sh
-rw-rw-r--. zgy zgy 4月 : test.sh [zgy@Web ~]$ ./test.sh #使用第二种方式"./"在当前目录下执行test.sh脚本文件,可以发现,这个地方无法自动补全。
-bash: ./test.sh: 权限不够 #提示:此处没有可执行权限
但是可以用source或者"."点号执行。
[zgy@Web ~]$ . test.sh
I am zgy
[zgy@Web ~]$ source test.sh
I am zgy
提示:"."点号和source命令的功能相同,都是读入脚本并可以执行脚本
给test.sh加执行权限
[zgy@Web ~]$ chmod u+x test.sh
[zgy@Web ~]$ ./test.sh
I am zgy
可以看到,给test.sh加完可执行权限就可以执行了。
现在测试第三种source或者"."点号的特殊的传递变量值到当前shell的例子
[zgy@Web ~]$ echo 'userdir=`pwd`'>testsource.sh #行的内容通常用echo很方便。
[zgy@Web ~]$ cat testsource.sh
userdir=`pwd`
[zgy@Web ~]$ sh testsource.sh
[zgy@Web ~]$ echo $userdir
#此处为空,并没有出现当前路径输出,这是为什么呢?
根据上面例子,可以发现,通过sh或bash命令执行过的脚本,脚本结束后在当前shell窗口查看userdir变量的值,发现变量值是空的。现在以同样的步骤改用source执行,然后再看看userdir变量的值
[zgy@Web ~]$ source testsource.sh
[zgy@Web ~]$ echo $userdir
/home/zgy
再看看系统Nfs服务的脚本如何使用”.”号的。
# Source function library.
. /etc/rc.d/init.d/functions
提示:操作系统及服务自带的脚本是学习的标杆和参考(虽然有时感觉不是很规范)
结论:
通过source或”.”点号加载执行过的脚本,在脚本结束后脚本中的变量值(包括函数)在当前Shell中依然存在,而是sh和bash则不行。
因此,在做Shell脚本开发时,如果脚本中有需求引用其他脚本的内容或者配置文件时,最好用”.”点号或source在脚本开头加载该脚本或配置文件,
然后再下面的内容用可以调用source加载的脚本及文件中的变量及函数等内容
某互联网公司Linux运维职位实际面试笔试
、已知如下命令返回结果,请问echo $user的返回的结果为()
[zgy@Web ~]$ cat test.sh
user=`whoami`
[zgy@Web ~]$ sh test.sh
[zgy@Web ~]$ echo $user
问:执行echo $user命令的结果是什么?
)当前用户
)zgy
)空(无内容输出) #这个是正确答案
Shell脚本开发基本规范及习惯
1)开头指定脚本解释器
#!/bin/sh或#!/bin/bash
2)开头加版权版本等信息
#Date: : -- #Author Created by zgy #Mail @qq.com #Function: This scripts function is... #Version 1.1
3)脚本中不用中文注释
尽量用英文注释,防止本机或切换系统环境后中文乱码的困扰
4)脚本以.sh为扩展名
例:script-name.sh
5)代码书写优秀习惯
1.成对内容的一次写出来,防止遗漏。如:
[]、{}、''、``、""
2.[]中括号两段要有空格,书写时即可留出空格[ ],然后在退格书写内容。
3.流程控制语句一次书写成,再添加内容,如:
if语句格式一次完成:
if 条件内容
then
内容
fi
for语句格式一次完成:
for
do
内容
done
提示:while和util,case等语句也是一样
6)通过缩进让代码易读
if 条件内容
then
内容
fi
提示:好的习惯可以避免很多不必要的麻烦,提升很多的工作效率。
一、Shell概述的更多相关文章
- shell概述与echo命令
一.Shell概述 1.什么是shell? 由此可见shell是用户与系统进行交互的接口,通过执行各种命令来完成时间处理与调度. 2.shell分类 Shell类别 易学性 可移植性 编辑性 快捷性 ...
- Shell概述1
Shell概述1 脚本文件内容(vim ex2) #!/bin/bash #If no arguments,then listing the current directory. #Otherwise ...
- Shell概述
一,Shell原理
- Linux系列教程(二十)——Linux的shell概述以及如何执行脚本
从这篇博客开始,我们将进入Linux的shell脚本的学习,这对于Linux学习爱好者而言是特别重要的一节,也是特别有意思的一节,shell 脚本就像我们知道的Java,php类似的编程语言一样,通过 ...
- HoloLens开发手记 - HoloLens shell概述 HoloLens shell overview
使用HoloLens时,shell是由你周围的世界和来自系统的全息图像构成.我们将这种空间成为混合世界(mixed world). shell包含了一个可以让你将全息图像和应用放置在世界中的开始菜单( ...
- 【第一章】Shell 概述
一.什么是Shell? shell是一个命令解释器,它不仅包含大量的命令以实现操作系统的对话,还可以实现定义变量.条件判断.循环控制.函数调用等功能. 作用:解释执行用户输入的命令及程序等. 从键盘输 ...
- Shell 概述、截取字符操作等
Shell 是用C语言编写的程序,便于用户与Linux内核系统进行交互. Linux的Shell种类众多,常见的有: Bourne Again Shell (/bin/bash) Bourne She ...
- Linux学习笔记 (八)Shell概述
一.什么是Shell? Shell是一个命令行解释器,它为用户提供了一个向Linux内核发送请求以便运行程序的界面系统级程序,用户可以用Shell来启动,挂起,停止甚至是编写一些程序.Shell还是一 ...
- hbase shell概述
hbase shell-general(常规指令):http://www.cnblogs.com/husky/p/6374867.html hbase shell-ddl(表定义指令):http:// ...
- Shell 01 shell概述
1.查看shells:/etc/shells /bin/sh /bin/bash /sbin/nologin /usr/bin/sh /usr/bin/bash /usr/sbin/nologin / ...
随机推荐
- vps批量管理,服务器批量管理,3389批量管理工具
注册的第一天,把我的工具弄上来.如果有一个软件,如果你有vps虚拟机,服务器,3389中的任意一种两种或全部,而且还是批量的,需要管理.那么,你可能会想找个软件来管理吧,毕竟,一个人忙不过来管理这么多 ...
- 2017 ACM-ICPC亚洲区域赛北京站J题 Pangu and Stones 题解 区间DP
题目链接:http://www.hihocoder.com/problemset/problem/1636 题目描述 在中国古代神话中,盘古是时间第一个人并且开天辟地,它从混沌中醒来并把混沌分为天地. ...
- 「CH2101」可达性统计 解题报告
CH2101 可达性统计 描述 给定一张N个点M条边的有向无环图,分别统计从每个点出发能够到达的点的数量.N,M≤30000. 输入格式 第一行两个整数N,M,接下来M行每行两个整数x,y,表示从x到 ...
- Linux 下解压.tar.gz文件报错 gzip:stdin:not in gzip format 的解决办法!
[root@hzp124 opt]# tar xzvf 1577255462-qypt.tar gzip: stdin: not in gzip formattar: Child returned s ...
- mock造数据
前端开发,需要和后台联调:很多时候,前端开发并不需要等后台完全写好接口在去联调,自己可以写死数据,渲染数据,加样式.后台人员有时会很忙,他没有时间写好返回所有的数据等等,特别是新开一个项目,从零开始的 ...
- 探究Dubbo的拓展机制: 下
承接上篇, 本篇博文的主题就是认认真真捋一捋, 看一下 Dubbo是如何实现他的IOC / AOP / 以及Dubbo SPI这个拓展点的 总览: 本篇的话总体上分成两部分进行展开 第一点就是 Dub ...
- 与drawable的较量(一)
前言 在android ui中drawable 是一个非常关键的要点,因为我们现在使用的花里胡哨的APP,都在胡里花哨的drawable 构建的. drawable,英文翻译为可拖拽的.说白了就是自己 ...
- 牛客网上的ST阶跃表
给你一个长为n的序列a和一个常数k 有m次询问,每次查询一个区间[l,r]内所有数最少分成多少个连续段,使得每段的和都 <= k 如果这一次查询无解,输出"Chtholly" ...
- Akka Java 中文文档
Akka Java 中文文档 Introduction What is Akka? | 什么是Akka? Why Akka? | 为什么选择Akka? Getting Started | Akka入门 ...
- nginx介绍与安装
1.nginx作用可以配置数十个场景 2.环境安装 环境确认 安装环境 yum -y install gcc gcc-c++ autoconf pcre-devel make automa ...