shell脚本之变量与状态码

目录:

前言

如何创建一个脚本

脚本调试

变量相关

变量的命令规则

bash中变量的种类

本地变量

环境变量

只读和位置变量

位置变量

查询变量

进程的退出状态与状态码

前言

在linux管理中,shell脚本很是重要,它可以帮助我们完成很多繁琐的工作,专注于更重要的事情上来,脚本的学习也是我们学习linux中所要遇到的比较困难的部分,因为它需要对vim,正则,逻辑,程序化语言有一定的熟悉,shell编程是过程式,解释执行的。它包括各种系统指令的组合,数据存储(变量,数组)、表达式、语句。

在shell脚本中,包含一些命令或声明,并符合一定格式的文本文件,在首行是shebang机制,如:

#!/bin/bash

#!/usr/bin/python

#!/usr/bin/perl

脚本在开头查找执行本脚本的程序,此程序就在第一行命令。Shell脚本经常用于自动化常用命令,执行系统管理和故障排除,创建简单的应用程序,处理文本或文件。

如何创建一个脚本

第一步,使用文本编辑器(vim)创建一个文件,一般都是以.sh结尾,在第一行必须包括shell声明#!(即shebang机制)我们一般使用#!/bin/bash

[[email protected] bin]# vim test.sh
 1 #!/bin/bash
 2 ~
 3 ~
 4 ~
 5 ~
 6 ~
 7 ~
 8 ~
 9 ~
10 ~
11 ~
12
13 -- INSERT --                                                                   1,12   All

第二步,添加注释,shell脚本中的注释都是以#开头,后面跟上注释内容(一般注释写什么,我们一会儿就会说到)

1 #!/bin/bash
2 #Filename: test.sh
3 #Revision: 1.0
4 #Date: 2017-8-2
5 #Author: hahaha
6 #Description: ################
~
~
~

第三步,编写脚本内容,脚本内容可以写我们常用的一些命令,比如查找我们磁盘中使用量最大的百分比等

  1 #!/bin/bash
  2 #Filename: disk.sh
  3 #Revision: 1.0
  4 #Date: 2017-8-2
  5 #Author: hahaha
  6 #Dessciption:
  7
  8 df | grep "dev/sd" | tr -s " " % | cut -d"%" -f5 | sort -nr | head -1
~
~
~
~
~                      

第四步,给予脚本执行权限,即chmod +x shellname.sh,最后我们就可以执行我们的脚本了

[[email protected] bin]# ll | grep "test.sh"
-rw-r--r--. 1 root root    0 Aug  3 16:06 test.sh
[[email protected] bin]# chmod +x test.sh
[[email protected] bin]# ll | grep "test.sh"
-rwxr-xr-x. 1 root root    0 Aug  3 16:06 test.sh 

接下来我们说说们可以在注释里写啥东西。

1.  第一行一般为调用使用的语言

2.  程序名,避免更改文件名为无法找到正确的文件

3.  版本号

4.  更改后的时间

5.  作者相关信息

6.该程序的作用,及注意事项

7. 最后是各版本的更新简要说明

比如说:

1 #!/bin/bash
2 # Filename: hello.sh
3 # Revision: 1.1
4 # Date: 2017/06/01
5 # Author: wang
6 # Description: This is the first script 

脚本调试

我们咋运行脚本之前,可以对脚本进行调试,这样可以保证我们的脚本出错的几率更低,一般我们常用的有两个参数:

检测脚本中的语法错误

bash -n /path/to/some_script

调试执行

bash -x /path/to/some_script

[[email protected] bin]# bash -x link.sh
+ netstat -tn
+ grep tcp
+ cut -d: -f6
+ sort -nr
+ uniq -c
+ tr -s ‘ ‘ :
      1 192.168.111.1

接下来我们开始与脚本内容相关的知识,基础知识包括变量(变量的种类,变量的命令规则,本地变量,环境变量,位置变量),执行后的状态及状态码,算数运算与赋值。

变量相关

在shell脚本中的变量是弱类型的变量,语言的运行时会隐式做数据类型转换。无须指定类型,默认均为字符型;参与运算会自动进行隐式类型转换,变量无须事先定义可直接调用。

变量的命令规则

1.  不能使程序中的保留字:例如if, for

2.  只能使用数字、字母及下划线,且不能以数字开头

3. 见名知义

4.  统一命名规则:驼峰命名法

1 for:错误
2 23var:错误
3 ip_w:正确
4 var:正确
5 _min:正确
6 someIp:正确

bash中变量的种类

根据变量的生效范围等标准:

本地变量:生效范围为当前shell进程;对当前shell之外的其它shell进程,包括当前shell的子shell进程均无效

环境变量:生效范围为当前shell进程及其子进程局部变量:生效范围为当前shell进程中某代码片断(通常指函数)

位置变量: $1, $2, ...来表示,用于让脚本在脚本代码中调用通过命令行传递给它的参数

特殊变量:

 $?, $0, $*, [email protected], $#,$$

在这些变量中,本地变量仅对当前shell有效,对子shell是没有效的。而环境变量对当前shell及其子shell都有效,我们可以用env查询所有的环境变量,用set查询本地变量和环境,我们有一点需要知道,在linux中变量声明以后会一直存在,除非我们把他们给删除掉,删除变量我们可以用unset varname

[[email protected] bin]# echo $A
string
[[email protected] bin]# unset A
[[email protected] bin]# echo $A

[[email protected] bin]# set | grep "^A"
ABRT_DEBUG_LOG=/dev/null
删除了A变量

本地变量

设置变量:

(1) 可以是直接字串; name=“root"

(2) 变量引用: name="$USER"

(3) 命令引用: name=`COMMAND` name=$(COMMAND)

引用变量:

${varname}

$varname

“$varname”

[[email protected] bin]# myName=BUG
[[email protected] bin]# echo $myName
BUG
[[email protected] bin]# echo "$myName"
BUG
[[email protected] bin]# echo ${myName}
BUG

"":弱引用,其中的变量引用会被替换为变量值

‘‘:强引用,其中的变量引用不会被替换为变量值,而保持原字符串

[[email protected] bin]# echo "$USER"
root
[[email protected] bin]# echo ‘$USER‘
$USER

转译:

\ 完全转译

""部分转译 \ ` ! $(""无法转译的字符)

‘‘ 完全转译

转译的原因是因为有些字符在linux下有特殊含义,但是,我们又需要用到它普通意义,所以我们需要对他们转译成非特殊字符供我们使用。

[[email protected] app]# echo "$20.0"
0.0
[[email protected] app]# echo "\$20.0"
$20.0
[[email protected] app]# echo ‘$20.0‘
$20.0
[[email protected] app]# echo "!ll"
echo "ll"
ll
[[email protected] app]# echo ‘!ll‘
!ll

环境变量

环境变量的声明:

export name=value

declare -x name=value

环境变量的引用:

$name

${name}

在前面我们已经说过如何查看我们的变量,但是,查看环境变量的命令还有几个,如:env,printenv,export,declare –x,在bash中还有一些内建的环境变量:

PATH:命令查找的路径

SHELL:我们使用的shell

USER:当前用户名

UID:当前用户UID

HOME:家目录

PWD:当前工作目录

SHLVL:当前所在的几级shell

LANG:使用的字符集

MAIL:邮箱路径

HOSTNAME:主机名

HISTSIZE:历史命令记录长度

_:上次执行的命令

[[email protected] app]# env
XDG_SESSION_ID=612
HOSTNAME=CT71  -----------------------------------------------------------------------主机名
SELINUX_ROLE_REQUESTED=
TERM=xterm
SHELL=/bin/bash  ---------------------------------------------------------------------使用的shell
HISTSIZE=1000  -----------------------------------------------------------------------历史命令记录长度
SSH_CLIENT=192.168.111.1 52880 22
SELINUX_USE_CURRENT_RANGE=
SSH_TTY=/dev/pts/2
USER=root  ---------------------------------------------------------------------------当前用户名
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00
... ...
MAIL=/var/spool/mail/root --------------------------------------------------------------邮箱路径
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin  --------------------命令查找路径
PWD=/app  ----------------------------------------------------------------------------当前的工作目录
LANG=en_US.UTF-8  --------------------------------------------------------------------使用的字符集
... ...

 SHLVL=1  -----------------------------------------------------------------------------当前所在的几级shell
 HOME=/root  --------------------------------------------------------------------------当前用户家目录
 LOGNAME=root
 SSH_CONNECTION=192.168.111.1 52880 192.168.111.110 22
 LESSOPEN=||/usr/bin/lesspipe.sh %s
 XDG_RUNTIME_DIR=/run/user/0
 OLDPWD=/root/bin
 _=/usr/bin/env  ----------------------------------------------------------------------上次执行的命令

只读和位置变量

我们可以在linux中设置只读变量,它的特点是只能声明,但不能修改和删除

声明只读变量:

readonly name

declare –r name

查看只读变量:

readonly –p

[[email protected] app]# readonly H=2134
[[email protected] app]# H=werq
-bash: H: readonly variable
[[email protected] app]# readonly -p
declare -r BASHOPTS="checkwinsize:cmdhist:expand_aliases:extglob:extquote:force_fignore:histappend:interactive_comments:login_shell:progcomp:promptvars:sourcepath"
declare -ir BASHPID
declare -r BASH_COMPLETION_COMPAT_DIR="/etc/bash_completion.d"
declare -ar BASH_REMATCH=‘()‘
declare -ar BASH_VERSINFO=‘([0]="4" [1]="2" [2]="46" [3]="1" [4]="release" [5]="x86_64-redhat-linux-gnu")‘
declare -ir EUID="0"
declare -r H="2134"
declare -ir PPID="57929"
declare -r S
declare -r SHELLOPTS="braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor"
declare -ir UID="0"
[[email protected] app]# unset -f S  删除只读变量
[[email protected] app]# echo $S

[[email protected] app]# 

declare是一个shell的内建命令,用来显示所有变量属性和和值的,它还有一些常用的参数,比如上面的declare –r是用来设置只读变量的,declare –f不仅显示变量,还显示函数,还有declare –x设置环境变量等

位置变量

位置变量其实就是在脚本代码中调用通过命令行传递给脚本的参数。我们可以通过外在的参数传递给脚本以实现与脚本的交互操作,增强脚本功能。

在脚本中的$1,$2,$3…分别对应着脚本外面的1个,第2个,第3参数,$0代表的是命令本身,$*是传递给脚本的所有参数,全部参数合为一个字符串

[email protected]是传递给脚本的所有参数,每个参数为独立字符串,$#是传递给脚本的参数的个数([email protected] $* 只在被双引号包起来的时候才会有差异)

set -- 清空所有位置变量

  1 #!/bin/bash
  2
  3 echo "$1"
~
~
-------------------------------------------
[[email protected] app]# chmod +x test.sh
[[email protected] app]# ll
total 4
-rwxr-xr-x. 1 root root 23 Aug  3 19:22 test.sh
[[email protected] app]# ./test.sh Hello
Hello
  1 #!/bin/bash
  2 echo "filename :$(basename $0)"
~
~
~      -----------------------------------------

[[email protected] app]# ./test2.sh
filename :test2.sh

  1 #!/bin/bash     #tt1.sh
  2 ./tt2.sh "[email protected]"
~
~
  1 #!/bin/bash    #tt2.sh
  2
  3 echo "[email protected]"
~
[[email protected] app]# ./tt1.sh 1 2 3 4 5
1 2 3 4 5
---------------------------------------------------------------------
  1 #!/bin/bash     #tt1.sh
  2 ./tt2.sh "$#"
~
~
  1 #!/bin/bash    #tt2.sh
  2
  3 echo "$#"
~
[[email protected] app]# ./tt1.sh 1 2 3 4 5
1

由于我不是在PATH所在的路径下执行的脚本所以直接执行脚本是找不到的,必须要跟上确定的路径./tt2.sh就是在本目录下执行tt2.sh脚本

查询变量

本地变量的查询

set (即查本地,也查环境)

[[email protected] app]# set | grep -C 4 "^PWD"
PROMPT_COMMAND=‘printf "\033]0;%[email protected]%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/~}"‘
PS1=‘[\[email protected]\h \W]\$ ‘
PS2=‘> ‘
PS4=‘+ ‘
PWD=/app
SELINUX_LEVEL_REQUESTED=
SELINUX_ROLE_REQUESTED=
SELINUX_USE_CURRENT_RANGE=
SHELL=/bin/bash

环境变量的查询

env

printenv

export

declare -x

[[email protected] app]# printenv
XDG_SESSION_ID=612
HOSTNAME=CT71
SELINUX_ROLE_REQUESTED=
TERM=xterm
SHELL=/bin/bash
HISTSIZE=1000
SSH_CLIENT=192.168.111.1 52880 22
SELINUX_USE_CURRENT_RANGE=
... ...

进程的退出状态与状态码

我们在系统中没执行一个命令都会开辟一个进程,配置一个PID,当程序运行结束后,即进程结束后,都会返回一个值给变量“?”,通过返回的值,我们就可以了解到这个进程执行的结果如何,在返回的中,0 代表执行成功,1-255代表着不同的失败,$?变量保存着最近的命令执行后的状态。

除了程序自动的赋值外,我们也可以手动自定义程序退出的状态码,特别是在我们写脚本时,通过条件语句进行判断时,自定义的退出码就派上大用场。

自定义退出状态码:

   exit[n] n={1..255}

注意:脚本中一旦遇到exit命令,脚本会立即终止;终止退出状态取决于exit命令后面的数字

注意:如果未给脚本指定退出状态码,整个脚本的退出状态码取决于脚本中执行的最后一条命令的状态码

  1 #!/bin/bash
  2
  3 echo "Myname is Tony!"
  4
  5 exit 1
  6
  7 echo "Show my name"
~
~
--------------------------------------------------
[[email protected] app]# chmod +x tt3.sh
[[email protected] app]# ./tt3.sh
Myname is Tony!

在这我们多说一点东西,如何查看进程以及PID,这里有几个变量和命令,我们来看一下:

变量$$:查看当前的PID

PPID:查看父进程的PID

SHLVL:显示当前的shell是几级shell

pstree:显示进程树

-p:同时显示进程的PID

ps –ef :显示进程信息

[[email protected] app]# echo $$
57933
[[email protected] app]# echo $PPID
57929
[[email protected] app]# pstree -p | grep -C 2 "bash"
           |                `-{rsyslogd}(2281)
           |-smartd(577)
           |-sshd(1401)---sshd(57929)---bash(57933)-+-grep(61485)
           |                                        `-pstree(61484)
           |-systemd-journal(367)
[[email protected] app]# echo $SHLVL
1
[[email protected] app]# ps -ef | grep "bash"
root        607      1  0 Jul31 ?        00:00:14 /bin/bash /usr/sbin/ksmtuned
root      57933  57929  0 14:09 pts/2    00:00:01 -bash
root      61495  57933  0 20:05 pts/2    00:00:00 grep --color=auto bash

p.MsoNormal,li.MsoNormal,div.MsoNormal { margin: 0cm; margin-bottom: .0001pt; text-align: justify; font-size: 12.0pt; font-family: Consolas }
h2 { margin-top: 13.0pt; margin-right: 0cm; margin-bottom: 13.0pt; margin-left: 0cm; text-align: justify; line-height: 173%; page-break-after: avoid; font-size: 16.0pt; font-family: "等线 Light" }
h3 { margin-top: 13.0pt; margin-right: 0cm; margin-bottom: 13.0pt; margin-left: 0cm; text-align: justify; line-height: 173%; page-break-after: avoid; font-size: 15.0pt; font-family: Consolas }
p.MsoToc2,li.MsoToc2,div.MsoToc2 { margin-top: 0cm; margin-right: 0cm; margin-left: 21.0pt; margin-bottom: .0001pt; text-align: justify; font-size: 12.0pt; font-family: Consolas }
p.MsoToc3,li.MsoToc3,div.MsoToc3 { margin-top: 0cm; margin-right: 0cm; margin-left: 42.0pt; margin-bottom: .0001pt; text-align: justify; font-size: 12.0pt; font-family: Consolas }
a:link,span.MsoHyperlink { color: #0563C1; text-decoration: underline }
a:visited,span.MsoHyperlinkFollowed { color: #954F72; text-decoration: underline }
p.MsoListParagraph,li.MsoListParagraph,div.MsoListParagraph { margin: 0cm; margin-bottom: .0001pt; text-align: justify; text-indent: 21.0pt; font-size: 12.0pt; font-family: Consolas }
span.2Char
{ font-family: "等线 Light"; font-weight: bold }
span.3Char
{ font-weight: bold }
.MsoChpDefault { font-size: 12.0pt; font-family: Consolas }
div.WordSection1 { }
ol { margin-bottom: 0cm }
ul { margin-bottom: 0cm }

时间: 2024-12-11 06:11:39

shell脚本之变量与状态码的相关文章

shell脚本分析apache日志状态码

一.首先将apache日志按天切割 vi /etc/httpd/conf/httpd.confErrorLog "|rotatelogs /var/log/httpd/%Y%m%derror_log 86400 480″CustomLog "|rotatelogs /var/log/httpd/%Y%m%daccess_log 86400 480″ combined 二.重启apache服 service httpd restart ##################apahce日志

Linux下shell脚本监控Tomcat的状态并实现自动启动

最近公司需要在Linux下监控tomcat的服务,一旦tomcat服务存在异常或者宕机,重启tomcat保证服务的正常运行,由于Linux下有Shell脚本可以实现此效果,下面是Linux下shell脚本监控Tomcat的状态并实现自动启动的步骤. 1.编写Shell脚本monitor.sh #!/bin/sh # func:自动监控tomcat脚本并且执行重启操作# author:EagleHao# date:2018-04-08# DEFINE # 获取tomcat进程ID(其中[grep

shell脚本之变量替换

代码如下 #!/bin/bash a=123 let "a += 1" echo a=$a echo b=${a/12/BB} echo "b=$b" 执行结果为 a=124 b=BB4 b=${a/12/BB} 变量a中的值12被替换为BB,所以$b=BB4 shell脚本之变量替换,布布扣,bubuko.com

Linux下的shell脚本编程-变量-算术表达式-判断语句-if分支语句

Linux下的shell脚本编程-变量-算术表达式-判断语句-if分支语句 一:实验环境 1):虚拟机 2):linux系统 二:实验目标 1): shell 基本语法 2):变量 3):表达式 4):判断语句 5): if表达式 三:实验脚本 第一块 一个简单的shell脚本程序 [[email protected] ~]# mkdir test [[email protected] test]# vim example1.sh #!/bin/bash #This is to show wha

Bash Shell脚本编程-变量知识

Shell:GUI  CLI 提供交互式接口:提高效率 命令行展开:~ ,{} 命令别名:alias 命令历史:history Globbing:*,?,[],[^] 命令补全:$PATH指定的目录下 路径补全:TAB键 管道:| 输入输出重定向:>    >> 提供编程环境: bash自动运行脚本机制 面向过程(以指令为中心组织数据)的编程模型 脚本编程 输入指令解决问题 程序是语句和表达式组成的 运行时根据一定流程来执行: 顺序执行 选择执行 循环执行 程序是指令+数据的 面向对象(

shell脚本基础----变量

1.1shell的定义 1.命令的堆积 2.特定的语法与特定的命令组成的文件 执行脚本命令 bash test.sh 不需要添加执行权限,使用解释器直接解释 sh tesh.sh ./tesh.sh 相对路径,需要添加执行权限 1.2shell脚本基础---变量 变量:用一个固定的字符串表示不固定的内容变量名称注意事项 1.不能以数字开头(包含字母.数字.下划线) 2.不能使用程序中的保留字(例如:if for) 3.不能跟系统中已有的环境变量重名(尽量不要全部使用大写,尽量不要用'_'下划线开

linux下使用smtp+shell脚本实现服务器存活状态监控

简单邮件传输协议 (Simple Mail Transfer Protocol, SMTP) 是在Internet传输email的事实标准, SMTP是一个相对简单的基于文本的协议.在其之上指定了一条消息的一个或多个接收者,然后消息文本会 被传输.SMTP使用TCP端口25. 一.配置环境 [[email protected] ~]# cat /etc/redhat-release CentOS Linux release 7.5.1804 (Core) #查看系统环境 [[email prot

20.1-20.4 shell:脚本,脚本结构与执行,date用法,shell脚本的变量

20.1 shell是什么 shell是系统跟计算机硬件交互时使用的中间介质,它只是系统的一个工具. 实际上,他在shell和计算机硬件之间还有一层东西--系统硬核.如果把计算机硬件比作一个人的躯体,那系统内核就是人的电脑.至于shell,把它比作人的五官似乎更贴切些. 用户直接面对的不是计算机硬件而是shell,用户把指令告诉shell,然后shell再传输给系统内核,接着内核再去支配计算机硬件去执行各种操作. shell是一种脚本语言  微信公众号:aming_linux  博客:blog.

linux中shell curl命令获取http状态码

通过curl的-w参数我们可以自定义curl的输出,%{http_code}代表http状态码 代码如下 复制代码 # curl -I -m 10 -o /dev/null -s -w %{http_code}  www.111cn.net 上面的输出是不含换行的,如果需要换行的话,加上\n 代码如下 复制代码 # curl -I -m 10 -o /dev/null -s -w %{http_code}  www.111cn.net 200# curl -I -m 10 -o /dev/nul