Shell脚本入门学习

shell脚本语言的使用

shell概述

shell 是一种脚本语言。

脚本:本质是一个文件,文件里面存放的是 特定格式的指令,系统可以使用脚本解析器 翻译或解析 指令 并执行(它不需要编译)。

举个例子,我想实现这样的操作:

1)进入到/tmp/目录;

2)列出当前目录中所有的文件名;

3)把所有当前的文件拷贝到/root/目录下;

4)删除当前目录下所有的文件。

简单的4步在shell窗口中需要你敲4次命令,按4次回车。这样是不是很麻烦?当然这4步操作非常简单,如果是更加复杂的命令设置需要几十次操作呢?那样的话一次一次敲键盘会很麻烦。

所以不妨把所有的操作都记录到一个文档中,然后去调用文档中的命令,这样一步操作就可以完成。其实这个文档呢就是shell脚本了,只是这个shell脚本有它特殊的格式。

shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。Shell 既是一种命令语言,又是一种程序设计语言。(应用程序 解析 脚本语言)。

Shell脚本能帮助我们很方便的去管理服务器,因为我们可以指定一个任务计划定时去执行某一个shell脚本实现我们想要需求。

这对于Linux系统管理员来说是一件非常值得自豪的事情。现在的139邮箱很好用,发邮件的同时还可以发一条邮件通知的短信给用户,利用这点,我们就可以在我们的Linux服务器上部署监控的shell脚本,比如网卡流量有异常了或者服务器web服务器停止了就可以发一封邮件给管理员,同时发送给管理员一个报警短信这样可以让我们及时的知道服务器出问题了。

c脚本编写

Linux 的内核、shell、基础命令程序,都是C语言编写的

yum install gcc -y  # 安装gcc编译

c语言脚本hello.c

# include<stdio.h>
void main(){
   
 printf("hello world!\n");
}

执行c语言脚本

gcc hello.c  # 默认编译生成a.out文件
ls
 a.out  hello  hello.c  master.tar.gz  test.sh
./a.out  # 执行编译之后的a.out文件
 hello world!
gcc hello.c -o hello   # -o表示编译成为自己想要的文件名字
ls
 a.out  hello  hello.c  master.tar.gz  test.sh
./hello  # 运行c脚本
 hello world!

Shell 环境

Shell 编程跟 JavaScript、php 编程一样,只要有一个能编写代码的文本编辑器和一个能解释执行的脚本解释器就可以了。

Linux 的 Shell 种类众多,常见的有:

  • Bourne Shell(/usr/bin/sh或/bin/sh)
  • Bourne Again Shell(/bin/bash)
    • 在一般情况下,人们并不区分 Bourne Shell 和 Bourne Again Shell,所以,像 #!/bin/sh,它同样也可以改为 #!/bin/bash
  • C Shell(/usr/bin/csh)
  • K Shell(/usr/bin/ksh)
  • Shell for Root(/sbin/sh)
  • ……

#! 告诉系统其后路径所指定的程序即是解释此脚本文件的 Shell 程序。

第一个shell脚本

打开文本编辑器(可以使用 vi/vim 命令来创建文件),新建一个文件 test.sh,扩展名为 sh(sh代表shell),扩展名并不影响脚本执行,见名知意就好,如果你用 php 写 shell 脚本,扩展名就用 php 好了。

shell脚本通常都是以.sh 为后缀名的,这个并不是说不带.sh这个脚本就不能执行,只是大家的一个习惯而已。

有一个问题需要约定一下,凡是自定义的脚本建议放到/usr/local/sbin/目录下,这样做的目的是:

一来可以更好的管理文档。

二来以后接管你的管理员都知道自定义脚本放在哪里,方便维护。

【shell脚本的基本结构以及如何执行】

shell脚本的基本结构以及如何执行

查看自己Linux系统的默认解析:echo $SHELL

echo $SHELL
/bin/bash

实例

#!/bin/bash
echo "Hello World !"

1、定义以开头:#!/bin/bash

单个"#"号代表注释当前行第一步:编写脚本文件

2、加上可执行权限

chmod +x xxxx.sh

默认我们用vim编辑的文档是不带有执行权限的,所以需要加一个执行权限,那样就可以直接使用’./filename’ 执行这个脚本了。

3、运行

三种执行方式 (./xxx.sh |bash xxx.sh| . xxx.sh

./xxx.sh :先按照 文件中#!指定的解析器解析

  • 如果#!指定指定的解析器不存在,才会使用系统默认的解析器

bash xxx.sh:指明先用bash解析器解析

使用sh命令去执行一个shell脚本的时候是可以加-x选项来查看这个脚本执行过程的,这样有利于我们调试这个脚本哪里出了问题。

sh -x return_test.sh
 + sayhello junma
 + '[' junma ']'
 + echo hello junma
 hello junma
 + echo 0
 0
 + sayhello jinlong
 + '[' jinlong ']'
 + echo hello jinlong
 hello jinlong
 + echo 0
 0
 + sayhello
 + '[' '' ']'
 + echo 'give me a name please!'
 give me a name please!
 + return 1
 + echo 1
 1
  • 如果bash不存在,才会使用默认解析器

. xxx.sh 直接使用默认解析器解析

三种执行情况:(重要)

shell是用户跟内核通信的几种方式之一

#!是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种 Shell。

\#!用来声明脚本由什么shell解释,否则使用默认shell

echo 命令用于向窗口输出文本。

shell脚本是一种脚本语言,我们只需使用任意文本编辑器,按照语法编写相应程序,增加可执行权限,即可在安装shell命令解释器的环境下执行。
你有没有用过这样的命令/etc/init.d/iptables restart,其实前面的/etc/init.d/iptables文件其实就是一个shell脚本,为什么后面可以跟一个”restart”? 这里就涉及到了shell脚本的预设变量。实际上,shell脚本在执行的时候后边是可以跟变量的,而且还可以跟多个。不妨、写一个脚本,看看就会明白了。

# test.sh
#!/bin/bash
sum=$[$1+$2]
echo $sum

执行过程如下:

sh -x test.sh 19 20
sum=39
echo 39
 39

在脚本中,你会不会奇怪,哪里来的$1$2,这其实就是shell脚本的预设变量,其中$1的值就是在执行的时候输入的$1,而$2的值就是执行的时候输入的$2,当然一个shell脚本的预设变量是没有限制的,这回你明白了吧。另外还有一个$0,不过它代表的是脚本本身的名字。不妨把脚本修改一下。

# test.sh
#!/bin/bash
sum=$[$1+$2]
echo "$0 $1 $2"

执行过程如下:

sh test.sh 20 20
 test.sh 20 20

退出状态码

每个命令执行后都会有对应的进程退出状态码,用来表示该进程是否是正常退出。
所以,在命令行中,在shell脚本中,经常会使用特殊变量$?判断最近一个前台命令是否正常退出。
通常情况下,如果$?的值:

  • 为0,表示进程成功执行,即正常退出

  • 非0,表示进程未成功执行,即非正常退出

  • 但非0退出状态码并不一定表示错误,也可能是正常逻辑的退出。

另外,在shell脚本中,所有条件判断(比如if语句、while语句)都以0退出状态码表示True,以非0退出状态码为False。

exit命令

exit命令可用于退出当前shell进程,比如退出当前shell终端、退出shell脚本,等等。

exit [N]

exit可指定退出状态码N,如果省略N,则默认退出状态码为0,即表示正确退出。

后台执行命令&

在命令的结尾使用&符号,可以将这个命令放入后台执行。
命令放入后台后,会立即回到shell进程,shell进程会立即执行下一条命令(如果有)或退出。
使用$!可以获取最近一个后台进程的PID。

sleep  20 &  
 [1] 14968
echo  $!
14968

使用wait命令可以等待后台进程(当前shell进程的子进程)完成:

wait [n1 n2 n3 ...]

不给定任何参数时,会等待所有子进程(即所有后台进程)完成。

sleep 5 &
 [2] 15316
 [1]   Done                    sleep 20
wait
echo haha
 haha

多命令组合

shell中有多种组合多个命令的方式。

  1. cmd1退出后,执行cmd2
cmd1;cmd2
  1. cmd1正确退出(退出状态码为0)后,执行cmd2
cmd1 && cmd2
  1. cmd1不正确退出后,执行cmd2
cmd1 || cmd2
  1. 逻辑结合:&&||可以随意结合
# cmd1正确退出后执行cmd2,cmd2正确退出后执行cmd3
cmd1 && cmd2 && cmd3...

# cmd1正确退出则执行cmd2,cmd1不正确退出会执行cmd3
# cmd1正确退出,但cmd2不正确退出,也会执行cmd3
cmd1 && cmd2 || cmd3

# cmd1正确退出会执行cmd3
# cmd1不正确退出会执行cmd2,cmd2正确退出会执行cmd3
cmd1 || cmd2 && cmd3
  1. 将多个命令分组:小括号或大括号可以组合多个命令
# 小括号组合的多个命令是在子shell中执行
# 即会先创建一个新的shell进程,再执行里面的命令
(cmd1;cmd2;cmd3)

# 大括号组合的多个命令是在当前shell中执行
# 大括号语法特殊,要求:
#   1.开闭括号旁边都有空白,否则语法解析错误(解析成大括号扩展)
#   2.写在同一行时,每个cmd后都要加分号结尾
#   3.多个命令可分行书写,不要求分号结尾
{
    cmd1;cmd2;cmd3; }
{
   
  cmd1
  cmd2
  cmd3
}

变量

顾名思义,变量就是其值可以变化的量。变量名是指向一片用于存储数据的内存空间。变量有局部变量,环境变量之分。

bash中基本数据类型只有字符串类型,连数值类型都没有(declare -i可强制声明数值类型)。

  • 局部变量就是指在某个Shell中生效的变量,对其他Shell来说无效。
    • 每个shell文件运行时都处于一个单独的进程中,独自分配内存空间。
  • 环境变量又称为全局变量。
    • 自定义环境变量
    • 系统预设的环境变量

shell变量是一种弱类型的变量,不像在C语言中,变量必须要先声明再使用。

shell中变量名区分大小写。

定义变量

变量名=变量值

注意:=两边不能有空格!

如:

name=Kitty
变量替换

变量替换是指在命令开始执行前,shell会先将变量的值替换到引用变量的位置处。
例如:

a="hello" 
echo $a world

在echo命令开始执行前,shell会取得变量a的值hello,并将它替换到命令行的$a处。于是,在echo命令开始执行时,命令行已经变成:

echo hello world

除了变量替换,Shell还会做其它替换:

  • 命令替换
  • 进程替换
  • 算术运算替换
  • 大括号扩展
  • 波浪号扩展
  • 路径扩展
    这些扩展和替换,都是shell在调用命令之前就完成的,这和其它语言解析代码的方式不一样。

学习Shell如何做命令行解析很重要,如果不掌握命令行解析,当遇到命令行语法错误后很可能会花掉大量无谓的时间去调试命令。而掌握命令行解析后,就会对命令生命周期了如执掌,不敢说一次就能写对所有命令行,但能节省大量调试时间,对写命令行和写脚本的能力也会上升一个层次。

引用变量

$变量名

如:

$name
清除变量值

unset 变量名

如:

unset name
只读变量
readonly num=10 # readonly只读
echo "num=$num"
 num=10
num=200
 -bash: num: readonly variable
查看环境变量
env
NVM_INC=/www/server/nvm/versions/node/v16.13.2/include/node
XDG_SESSION_ID=463
HOSTNAME=lw
NVM_CD_FLAGS=
TERM=xterm
SHELL=/bin/bash
HISTSIZE=1000
SSH_CLIENT=183.230.190.196 63586 22
SSH_TTY=/dev/pts/0
NVM_DIR=/www/server/nvm
USER=root
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz
  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值