shell脚本编程基础篇

==============================================================================

概述:

shell脚本在Linux系统管理员的运维工作中非常重要。shell脚本能够帮助我们很方便的管理服务器,因为我们可以指定一个任务计划,定时的去执行某一个脚本以满足我们的需求。本篇将从编程基础、脚本基本格式、变量、运算、条件测试这几个方面详细介绍shell脚本编程的基础内容,也是我们必须要掌握熟练的内容。

==============================================================================

Bash为用户提供了编程环境

 1.编程环境

★程序:指令+数据(或者:算法+数据结构)

  • 指令:由程序文件提供;

  • 数据:I/O设备、文件、管道、变量

★程序编程风格有两种:

◆过程式:以指令为中心来组织代码,数据服务于代码;

特点:

  • 顺序执行;

  • 循环执行;

  • 选择执行;

shell 程序,是一个过程式的解释器,提供了编程能力,然后解释执行;

◆对象式:以数据为中心来组织代码,围绕数据来服务于指令

  • 类(class):实例化对象 method;

  • 代表:java,C++,Python

★程序的执行方式:

  • 计算机:只能识别二进制文件,所以运行的是二进制指令(机器语言)

程序的执行过程:

  • 先把源码程序翻译成机器语言(生成可执行的文件),然后解释执行。对于过程式编程语言而言,把一行源程序翻译成机器语言,然后执行,再翻译下一行的源码程序为机器语言,然后再执行;

  • 对于计算机而言,它能识别的只能是二进制文件,因此其所运行的其实是二进制指令,这些二进制指令我们称之为机器语言,属于低级语言,相反高级语言是指,程序员编程所使用的语言,是人们比较容易理解的语言;

计算机编程语言:

◆低级:

  • 机器语言、汇编语言

◆高级:

  • 编译过程:高级语言(源代码)-->编译器(编译)-->目标代码 , 如:  c、c++、jave

  • 解释过程:高级语言(源代码)-->解释器(运行时启动解释器,由解释器边解释边运行)-->机器代码 , 如 :shell、perl、python

根据其编程过程中功能的实现是调用库还是调用外部的程序文件:

◆shell脚本编程:

  • 利用系统上的命令及编程组件进行编程;

◆完整编程:

  • 利用库和编程组件进行编程

★shell编程:过程式编程,解释执行,依赖于外部程序文件运行

  • 是一个过程式的解释器,提供了编程能力,然后解释执行。

编程语言的基本结构:

  • 数据存储:变量、数组

  • 表达式:a + b

  • 语句:if语句

shell脚本是什么?

  • shell脚本其实就是以一系列命令组合起来的文本文件,这些命令组合起来完成一个或者一项功能。

  • 但很多命令不具有幂等性,需要用程序逻辑来判断运行条件是否满足,以避免其运行中发生错误。

shell脚本的组成部分

 1.格式及用途:

★shell脚本

  • shell脚本是包含一些命令或声明,并符合一定格式的文本文件;

shell程序开头的环境指定:

  • 我们称之为shebang(顶格写):解释器路径,用于指明解释执行当前脚本的解释器程序文件;

◆常见解释器:

  • #!/bin/bash(顶格写)

  • #!/usr/bin/python

  • #!/usr/bin/perl

shell脚本的用途有:

  • 自动化常用命令;

  • 执行系统管理和故障排除;

  • 创建简单的应用程序;

  • 处理文本或文件;

 2.创建及运行shell脚本

★创建shell脚本

  • shell脚本通常都是以 .sh 为后缀名的

步骤如下:

◆第一步:使用(vim)文本编辑器来创建文本文件

  • 第一行必须包括shell声明序列:#!

  • 添加注释:#(注释以#开头 ,后面跟一些相关注释内容、作者、创建日期或版本等);

  • 代码注释:

  • 缩进,适度添加空白行

◆第二步:运行脚本(相当于开了一个子进程,bash--bash-)

※给予执行权限,并直接运行此程序文件:在命令行上指定脚本的绝对或相对路径

  • chmod +x /PATH/TO/SCRIPT_FILE

  • /PATH/TO/SCRIPT_FILE

※直接运行解释器:将脚本作为解释器程序的参数运行

  • bash /PATH/TO/SCRIPT_FILE

★脚本调试

检测脚本中的语法错误

  • bash -n /path/to/some_script

调试执行

  • bash -x /path/to/some_script

注意:

  • 脚本中的空白行会被解释器忽略;

  • 脚本中除了shebang,余下所有以#开头的行,都会被视作注释行而被忽略;此即为注释行;

  • shell脚本的运行是通过运行一个子shell进程实现的;

演示:

# 创建脚本
[root@centos7 ~]# echo $PATH
/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin[root@centos7 ~]# mkdir bin
[root@centos7 ~]# cd bin
[root@centos7 bin]# vim first.sh
#!/bin/bash
#author:taotao
#version:centos 7.2
#description:This is my first shell scriptdate
echo "Hello world!"
echo "心有理想,春暖花开"# 运行脚本(直接运行解释器)
[root@centos7 ~]# bash first.sh
2017年 02月 12日 星期日 21:23:00 CST
Hello world!
心有理想,春暖花开[root@centos7 bin]# sh first.sh
2017年 02月 12日 星期日 21:23:31 CST
Hello world!
心有理想,春暖花开# 给予执行权限,运行脚本(因为命令的环境变量中包含/root/bin 所以,可以直接运行脚本命令,他会自动去环境变量中PATH中去寻找执行)
[root@centos7 bin]# ll first.sh
-rw-r--r-- 1 root root 151 2月  12 21:14 first.sh
[root@centos7 bin]# chmod +x first.sh
[root@centos7 bin]# ll first.sh
-rwxr-xr-x 1 root root 151 2月  12 21:14 first.sh[root@centos7 ~]# first.sh
2017年 02月 13日 星期一 09:54:17 CST
Hello world!
心有理想,春暖花开[root@centos7 ~]# ./bin/first.sh # 也可以给绝对路径运行脚本命令
2017年 02月 12日 星期日 21:25:59 CST
Hello world!
心有理想,春暖花开# 检查脚本中的语法错误(没有结果就是最好的结果)
[root@centos7 bin]# bash -n first.sh # 调试执行
[root@centos7 bin]# bash -x first.sh
+ date
2017年 02月 12日 星期日 21:27:40 CST
+ echo 'Hello world!'
Hello world!
+ echo $'\345\277\203\346\234\211\347\220\206\346\203\263\357\274\214\346\230\245\346\232\226\350\212\261\345\274\200'
心有理想,春暖花开

shell脚本中的变量

 1.简介

★变量:命名的存储空间

  • 变量名+指向的内存空间

◆数据存储方式:ASCII

  • 字符:

  • 数值:整型,浮点型

变量赋值:

  • name=value

变量类型及作用:

◆作用:

  • 数据存储格式;

  • 参与的运算;

  • 表示的数据范围,

◆类型:

  • 字符:

  • 数值:整型,浮点型

变量替换:

  • 把变量名出现的位置替换为其所指向的内存空间中的数据;

变量引用:

  • ${var_name}

  • 或者:$var_name   如:echo $SHELL

编程语言分类:

强类型:

  • 定义变量时必须指定类型、参与运算必须符合类型要求;调用未声明变量会产生错误

  • 如:java,python

弱类型:

  • bash把所有变量统统视为字符型;

  • bash中的变量无需事先声明,可直接调用,相当于把声明和赋值过程同时实现;

  • 参与运算会自动进行隐式类型转换;

  • bash不支持浮点数

★变量名命名法则:

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

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

  • 见名知义;

统一命名规则:

  • 驼峰命名法(多单词):大驼峰是每个单词的第一个字母大写,小驼峰是第一个单词的字母小写,后面的单词大写  (jave中用的较多)

演示:

1.自定义变量与引用

[root@centos7 ~]# var=123
[root@centos7 ~]# echo $var
123

2.Shell中所有变量引用使用$符,后跟变量名。

有时个别特殊字符会影响正常引用,那么需要使用${VAR},例如:

[root@centos7 ~]# var=123
[root@centos7 ~]# echo $var
123
[root@centos7 ~]# echo $var_ #Shell允许VAR_为变量名,所以此引用认为这是一个有效的变量名,故此返回空[root@centos7 ~]# echo ${var}
123

还有时候变量名与其他字符串紧碍着,也会误认为是整个变量:

[root@centos7 ~]# echo $var456
[root@centos7 ~]# echo ${var}456
123456

3.将命令结果作为变量值

[root@centos7 ~]# var=`echo 123`
[root@centos7 ~]# echo $var
123
[root@centos7 ~]# var=$(echo 456)
[root@centos7 ~]# echo $var
456

2.bash 变量种类

★根据变量的生效范围等标准可分为:

本地变量:

  • 生效范围为当前shell进程;对当前shell之外的其它shell进程,包括当前shell的子shell进程均无效;

环境变量:

  • 生效范围为当前shell进程及其子进程(父进程,和子进程);

局部变量:

  • 生效范围为当前shell进程中某代码片断(通常指函数上下文);

位置参数变量:

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

特殊变量:

  • $?, $0, $*, $@, $#,shell内置的有特殊功用的变量

shell变量详述

 1.本地变量

★本地变量:

  • 生效范围为当前shell进程;对当前shell之外的其它shell进程,包括当前shell的子shell进程均无效;

变量赋值:

  • name=value

可以使用引用value:

  • 可以是直接字串:name=“root" (定义变量的格式:变量名=变量的值)

  • 变量引用:name="$USER" (引用变量时需要加上符号$,)

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

变量引用:${name}, $name

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

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

显示已定义的所有变量:set

撤销变量:unset name(注意:此处非变量引用,无$)

演示:

# 在当前bash中定义变量
[root@centos7 ~]# first_name=tao
[root@centos7 ~]# echo $first_name
tao# 在当前shell中开启一个子shell
[root@centos7 ~]# bash
===========================================Welcome Everbody心有理想,春暖花开!!!2017-02-12 22:51:59 星期日
===========================================
[root@centos7 ~]# pstree
systemd─┬─NetworkManager───2*[{NetworkManager}]├─abrt-dbus───2*[{abrt-dbus}]├─2*[abrt-watch-log]├─abrtd├─agetty├─alsactl├─atd├─auditd─┬─audispd─┬─sedispatch│        │         └─{audispd}│        └─{auditd}├─automount───4*[{automount}]├─chronyd├─crond├─cupsd├─dbus-daemon├─gssproxy───5*[{gssproxy}]├─lsmd├─lvmetad├─master─┬─pickup│        └─qmgr├─polkitd───5*[{polkitd}]├─rsyslogd───2*[{rsyslogd}]├─smartd├─sshd───sshd───bash───bash───pstree  # 证明为子shell├─systemd-journal├─systemd-logind├─systemd-udevd├─tuned───4*[{tuned}]└─wpa_supplicant#说明 本地变量的作用范围仅为当前shell,对子shell无效
[root@centos7 ~]# echo $first_name# 退出当前子shell
[root@centos7 ~]# exit
exit[root@centos7 ~]# echo $first_name
tao
[root@centos7 ~]# unset first_name  # 撤销变量
[root@centos7 ~]# echo $first_name

2.环境变量

★环境变量

  • 生效范围为当前shell进程及其子进程(父进程,和子进程);

变量声明、赋值:

  • export name=VALUE

  • declare -x name=VALUE

变量引用:

  • $name,${name} (大括号必要情况系下要添加,为了区分谁是变量)

显示所有环境变量:

  • export

  • env

  • printenv

撤销变量:

  • unset name

bash内嵌了许多环境变量(通常为全大写字符),用于定义bash的工作环境:

  • PATH, SHELL, USRE,UID, HISTSIZE, HOME, PWD, OLDPWD, HISTFILE, PS1

注意:

  • 环境变量和本地变量都是针对于当前终端有效,一但退出当前终端,再登录之后,之前定义的环境变量就消失了。

演示:

# 在当前shell中定义环境变量
[root@centos7 ~]# export first_name=taotao
[root@centos7 ~]# echo $first_name=taotao
taotao=taotao#  在当前shell中开启一个子shell
[root@centos7 ~]# bash# 说明,环境变量的作用范围仅为父shell和子shell(在其他终端登录不起作用)
[root@centos7 ~]# echo $first_name
taotao
[root@centos7 ~]# exit
exit
[root@centos7 ~]# echo $first_name
taotao#撤销环境变量
[root@centos7 ~]# unset first_name
[root@centos7 ~]# echo $first_name

2.显示所有环境变量

[root@centos7 ~]# export
declare -x DISPLAY="localhost:13.0"
declare -x HISTCONTROL="ignoredups"
declare -x HISTSIZE="1000"
declare -x HOME="/root"
declare -x HOSTNAME="centos7"
declare -x JAVA_HOME="/usr"
declare -x KDEDIRS="/usr"
declare -x LANG="zh_CN.utf8"
declare -x LESSOPEN="||/usr/bin/lesspipe.sh %s"
declare -x LOGNAME="root"
declare -x 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=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:"
declare -x MAIL="/var/spool/mail/root"
declare -x OLDPWD
declare -x PATH="/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin"
declare -x PWD="/root"
declare -x QTDIR="/usr/lib64/qt-3.3"
declare -x QTINC="/usr/lib64/qt-3.3/include"
declare -x QTLIB="/usr/lib64/qt-3.3/lib"
declare -x QT_GRAPHICSSYSTEM_CHECKED="1"
declare -x QT_PLUGIN_PATH="/usr/lib64/kde4/plugins:/usr/lib/kde4/plugins"
declare -x SHELL="/bin/bash"
declare -x SHLVL="1"
declare -x SSH_CLIENT="192.168.1.104 56684 22"
declare -x SSH_CONNECTION="192.168.1.104 56684 192.168.1.113 22"
declare -x SSH_TTY="/dev/pts/3"
declare -x TERM="xterm"
declare -x USER="root"
declare -x XDG_RUNTIME_DIR="/run/user/0"
declare -x XDG_SESSION_ID="63"

3.只读和位置参数变量

★只读变量:

  • 只读变量无法重新赋值,并且不支持撤销(一般针对常量,可以再次声明为一个环境变量)

  • 存活时间为当前shell进程的生命周期,随shell进程终止而终止;

定义方法:

  • readonly name

  • declare -r name ;declare -rx name(即是一个常量又是一个环境变量)

★位置变量:

  • 在脚本代码中调用通过命令行传递给脚本参数

引用方式:

  • $1, $2, ...,${10},${11}:对应第1、第2等参数;

轮替:

  • shift [n] :位置参数轮替(会踢掉左边的参数);

★特殊变量

  • $0:表示脚本文件路径本身

  • $*:传递给脚本的所有参数,全部参数合为一个字符串

  • $@:传递给脚本的所有参数,每个参数为独立字符串

  • $#:传递给脚本的参数的个数

注意:

  • $@ $* 只在被双引号包起来的时候才会有差异

演示:

1.只读变量

[root@centos7 ~]# readonly first_name=xiuxiu
[root@centos7 ~]# echo $first_name
xiuxiu[root@centos7 ~]# first_name=taotao
-bash: first_name: 只读变量[root@centos7 ~]# unset first_name
-bash: unset: first_name: 无法反设定: 只读 variable

2.位置变量

# 定义脚本可接受命令行传递的参数
[root@centos7 bin]# vim arg.sh
#!/bin/bash
#author:taotao
#description:测试位置参数变量echo "The 1st arg is $1"
echo "The 1st arg is $2"
echo "The 1st arg is $3"
echo "The all args are $*"
echo "The all args is $@"
echo "The all numbers is $#"
echo "The script_name is `basename $0`"  # 取文件的基名# 向命令行传递参数
[root@centos7 bin]# bash arg.sh aaa bbb ccc
The 1st arg is aaa
The 1st arg is bbb
The 1st arg is ccc
The all args are aaa bbb ccc
The all args is aaa bbb ccc
The all numbers is 3
The script_name is arg.sh# shift 用法
[root@centos7 bin]# cat shift.sh
#!/bin/bash
#author:tao
#description:测试shift的用法echo "1st arg is $1"
echo "all args are $*"
shift                 # 跳过1个参数
echo "1st arg is $1"
echo "all args are $*"
shift                 # 再跳过1个参数
echo "1st arg is $1"
echo "all args are $*"[root@centos7 bin]# shift.sh one two three
1st arg is one
all args are one two three
1st arg is two
all args are two three
1st arg is three
all args are three

3.编写脚本,判断给出文件的行数

[root@centos7 bin]# vim lines.sh
#!/bin/bash
#author:taotao
#description:给定任意文件,判断文件的行数linecout=$(wc -l $1 |cut -d' ' -f1)
echo "$1 has $linecout lines"[root@centos7 bin]# bash lines.sh /etc/passwd
/etc/passwd has 46 lines

bash的配置文件

1.生效范围分类

★按照生效范围划分:

全局配置文件:对所有用户都生效

  • /etc/profile

  • /etc/profile.d/*.sh

个人配置文件:仅对当前用户有效

  • ~/.bash_profile

  • ~/.bashrc

 2.shell登录类型

★交互式登录shell进程:

  • 直接通过某终端输入账号密码后登录打开的shell进程;

  • 使用su命令:“su - UserName”执行的登录切换;

执行顺序:

  • /etc/profile --> /etc/profile.d/*.sh --> ~/.bash_profile--> ~/.bashrc--> /etc/bashrc

★非交互式登录shell进程:

  • suUserName 执行的登录切换;

  • 图形界面下打开的终端;

  • 运行脚本

执行顺序:

  • ~/.bashrc--> /etc/bashrc--> /etc/profile.d/*.sh

 3.功能划分,存在两类

★profile类:为交互式登录的shell进程提供配置;

全局:对所有用户都生效

  • /etc/profile

  • /etc/profile.d/*.sh

用户个人:仅对当前用户生效

  • ~/.bash_profile

功用:

  • 用于定义环境变量;

  • 运行命令或脚本

bashrc类:为非交互式登录的shell进程提供配置;

全局:

  • /etc/bashrc

用户个人:

  • ~/.bashrc

功用:

  • 定义本地变量;

  • 定义命令别名;

注意:

  • 仅管理员可修改全局变量

 4.编辑配置文件生效

★特性:

  • 命令行中定义的特性,例如变量名和别名作用域为当前shell进程的生命周期;

  • 配置文件中定义的特性,只对随后新启动的shell进程有效

★让通过配置文件定义的特性立即生效:

  1. 退出并重新登录;

  2. 让shell进程重读配置文件

  • ~]# source /PATH/TO/CONF_FILE

  • ~]# . /PATH/TO/CONF_FILE

演示:

 1.定义个人配置

[root@centos7 ~]# vim .bashrc
# .bashrc# User specific aliases and functionsalias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
alias cdnet='cd /etc/sysconfig/network-scripts/'  # 定义别名# Source global definitions
if [ -f /etc/bashrc ]; then. /etc/bashrc
fi#定义本地变量PS1
PS1="\[\e[36;40m\][\[\e[32;40m\]\u\[\e[0m\]@\[\e[33;40m\]\h \[\e[36;40m\]\W\[\e[36;40m\]]\[\e[0m\]\\$ "# 这时查看alias命令,发现还没有定义的别名cdnet,说明还没有生效
[root@centos7 ~]# alias
alias cp='cp -i'
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l.='ls -d .* --color=auto'
alias ll='ls -l --color=auto'
alias ls='ls --color=auto'
alias mv='mv -i'
alias rm='rm -i'
alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'# 重读配置文件,再次查看,发现已经生效
[root@centos7 ~]# . .bashrc
[root@centos7 ~]# alias
alias cdnet='cd /etc/sysconfig/network-scripts/'
alias cp='cp -i'
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l.='ls -d .* --color=auto'
alias ll='ls -l --color=auto'
alias ls='ls --color=auto'
alias mv='mv -i'
alias rm='rm -i'
alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'
[root@centos7 ~]# cdnet
[root@centos7 network-scripts]# cd

2.定义全局配置

[root@centos7 ~]# cd /etc/profile.d/
[root@centos7 profile.d]# ls
256term.csh  abrt-console-notification.sh  colorgrep.csh  colorls.csh  java.sh  kde.sh    lang.sh   less.sh  qt-graphicssystem.csh  qt.sh    vim.sh      which2.csh
256term.sh   bash_completion.sh            colorgrep.sh   colorls.sh   kde.csh  lang.csh  less.csh  qt.csh   qt-graphicssystem.sh   vim.csh    which2.sh[root@centos7 profile.d]# vim welcome.sh
#!/bin/bashecho -e "\e[32m===========================================\e[0m"echo -e "\e[36m         Welcome Everbody\e[0m"
echo -e "\e[40;35;1m        心有理想,春暖花开!!!\e[0m"
echo -e "\e[36m      `date "+%F %H:%M:%S %A"`"echo -e "\e[32m===========================================\e[0m"#对于重新登陆的用户生效
[d:\~]$ ssh root@192.168.1.113[d:\~]$ Connecting to 192.168.1.113:22...
Connection established.
To escape to local shell, press 'Ctrl+Alt+]'.Last login: Mon Feb 13 11:32:31 2017 from 192.168.1.104
===========================================Welcome Everbody心有理想,春暖花开!!!2017-02-13 11:33:06 星期一
===========================================#=================================================================================
# 也可以定义环境变量
[root@centos7 profile.d]# vim ps1.sh
PS1="\[\e[36;40m\][\[\e[32;40m\]\u\[\e[0m\]@\[\e[33;40m\]\h \[\e[36;40m\]\W\[\e[36;40m\]]\[\e[0m\]\\$ "[root@centos7 profile.d]# vim java.sh
export JAVA_HOME=/usr#重读配置文件生效
[root@centos7 profile.d]# . ./ps1.sh
[root@centos7 profile.d]# . ./java.sh

bash特性之---多命令执行

★方式:

复合式: 命令会一个接一个的执行

  • ~]# COMMAND1;COMMAND2;COMMAND3;...  (如:date; who | wc -l )

子shell:所有的输出都被发送给单个STDOUT和STDER

  • 如:(date; who | wc -l ) >>/tmp/trace

演示:

# 按顺序执行
[root@centos7 ~]# date;who |wc -l
2017年 02月 19日 星期日 11:50:21 CST
2# 为子shell,括号中的执行结束后,再管道
[root@centos7 ~]# (date;who) |wc -l
3[root@centos7 ~]# date;who
2017年 02月 19日 星期日 11:51:24 CST
root     tty1         2017-02-19 11:50
root     pts/0        2017-02-19 11:02 (192.168.1.100)

Bash中的算术运算和逻辑运算

 1.算术运算

★bash中的算术运算

  • bash会对数字执行隐式的类型转化

运算操作符

  • +,-, *, /, % 取模(取余), **(乘方)

bash的算术运算的实现方式(格式)

  • let VAR=算术运算表达式(查看结果echo $VAR)

  • VAR=$[算术运算表达式] (可以变量赋值也可以直接写算术表达式,如:echo $[5+6])

  • VAR=$((算术运算表达式))  (同上)

  • VAR=$(expr $ARG1 $OP $ARG2)

注意:

  • 乘法符号在有些场景中需要转义

★bash中有内建的随机数生成器

  • $RANDOM(1-32767)

示例:echo $[$RANDOM%50] :0-49之间随机数

★赋值

增强型赋值:

  • 变量做某种算数运算后回存至此变量中;

  • +=, -=, *=, /=, %=

  • 使用方法:let varOPEvalue

示例:

let count+=3 即 count=count+3

自增自减

  • var=$[$var+1]

  • let var+=1 即 let var++

  • let var-=1 即 let var--

演示:

1.let VAR=算术表达式

[root@centos7 ~]# let var=5+6
[root@centos7 ~]# echo $var
11[root@centos7 ~]# num1=2
[root@centos7 ~]# num2=5
[root@centos7 ~]# let var=$num1+$num2
[root@centos7 ~]# echo $var
7

2. var=$[算术表达式] , var=$((算术表达式))

[root@centos7 ~]# echo $[$num1+$num2]
7[root@centos7 ~]# echo $((5+6))
11[root@centos7 ~]# num=$[2**3]  #变量赋值
[root@centos7 ~]# echo $num
8[root@centos7 ~]# echo $[2**3]
8

3.VAR=$(expr $ARG1 $OP $ARG2)

[root@centos7 ~]# expr $num1 + $num2
7
[root@centos7 ~]# sum=$(expr $num1 + $num2)  #为命令引用,注意空格
[root@centos7 ~]# echo $sum
7[root@centos7 ~]# expr 5 + 6
11

4.declare –i var= 数值(提前声明为数字的整数类型)

# 声明一个数字的整数类型,然后再运算
[root@centos7 ~]# declare -i i=100
[root@centos7 ~]# declare -i j=200
[root@centos7 ~]# declare -i k=i+j
[root@centos7 ~]# echo $k
300

5.echo ‘算术表达式’ | bc

6.echo $[$RANDOM%6] :0-5之间随机数

# 表示0-5
[root@centos7 ~]# echo $[$RANDOM%6]
4
[root@centos7 ~]# echo $[$RANDOM%6]
3
[root@centos7 ~]# echo $[$RANDOM%6]
5
[root@centos7 ~]# echo $[$RANDOM%6]
1
[root@centos7 ~]# echo $[$RANDOM%6]
2
[root@centos7 ~]# echo $[$RANDOM%6]
3
[root@centos7 ~]# echo $[$RANDOM%6]
1
[root@centos7 ~]# echo $[$RANDOM%6]
1
[root@centos7 ~]# echo $[$RANDOM%6]
1
[root@centos7 ~]# echo $[$RANDOM%6]
4
[root@centos7 ~]# echo $[$RANDOM%6]
5
[root@centos7 ~]# echo $[$RANDOM%6]
0
[root@centos7 ~]# echo $[$RANDOM%6]
1# 表示1-6
[root@centos7 ~]# echo $[$RANDOM%6+1]
4
[root@centos7 ~]# echo $[$RANDOM%6+1]
6
[root@centos7 ~]# echo $[$RANDOM%6+1]
3
[root@centos7 ~]# echo $[$RANDOM%6+1]
6
[root@centos7 ~]# echo $[$RANDOM%6+1]
4
[root@centos7 ~]# echo $[$RANDOM%6+1]
4
[root@centos7 ~]# echo $[$RANDOM%6+1]
1
[root@centos7 ~]# echo $[$RANDOM%6+1]
5
[root@centos7 ~]# echo $[$RANDOM%6+1]
6
[root@centos7 ~]# echo $[$RANDOM%6+1]
2
[root@centos7 ~]# echo $[$RANDOM%6+1]
6
[root@centos7 ~]# echo $[$RANDOM%6+1]
1
[root@centos7 ~]# echo $[$RANDOM%6+1]
4

7.增强型赋值

[root@centos7 ~]# let var=2+3
[root@centos7 ~]# echo $var
5
[root@centos7 ~]# let var+=2
[root@centos7 ~]# echo $var
7
[root@centos7 ~]# let var+=1
[root@centos7 ~]# echo $var
8
[root@centos7 ~]# var=$[$var+1]
[root@centos7 ~]# echo $var
9

 2.逻辑运算

★bash中的逻辑运算

  • 在shell编程当中支持一些逻辑运算:true(1),false(0)

与运算

  • 1 && 1 = 1

  • 1 && 0 = 0

  • 0 && 1 = 0

  • 0 && 0 = 0

或运算

  • 1 || 1 = 1

  • 1 || 0 = 1

  • 0 || 1 = 1

  • 0 || 0 = 0

非运算

  • ! 1 =0

  • ! 0 =1

★短路法则

短路与(&&):COMMAND1 && COMMAND2

  • 第一个为0,结果必定为0;

  • 第一个为1,第二个必须要参与运算;

  • COMMAND1为假,则COMMAND2不会再执行;

  • 否则,COMMAND1为真,则COMMAND2必须执行;

短路或(||):COMMAND1 || COMMAND2

  • 第一个为1,结果必定为1;

  • 第一个为0,第二个必须要参与运算;

  • COMMAND1为“真”,则COMMAND2不会再执行;

  • 否则,COMMAND1为“假”,则COMMAND2必须执行;

异或:^

  • 异或的两个值,相同为假,不同为真

示例:

  • ~]# id $username || useradd $username  如果用户不存在就创建,存在就显示id信息

转载于:https://blog.51cto.com/1992tao/1837636

1.shell脚本编程——基础篇(一)相关推荐

  1. Linux基础篇--shell脚本编程基础

    Linux基础篇–shell脚本编程基础 本章内容概要  编程基础  脚本基本格式  变量  运算  条件测试  配置用户环境 7.1 编程基础 程序:指令+数据 程序编程风格:   过程式:以指令为 ...

  2. linux基础—课堂随笔_03 SHELL脚本编程基础

    shell脚本编程基础 条件选择:if语句 选择执行: 注意:if语句可嵌套 单分支 if(开头)判断条件:then 条件为真的分支代码  fi(结尾) 双分支 if(开头)判断条件:then 条件为 ...

  3. Linux Shell脚本编程基础

    2 Linux Shell脚本编程基础 发表于: Linux, Shell, UNIX, 资源分享 | 作者: 谋万世全局者 标签: Linux,Shell,编程基础,脚本 本文作者:Leal 授权许 ...

  4. Linux shell 脚本编程-实战篇(三)

    继: Linux shell 脚本编程-实战篇(二) 3. 一些小有意思的脚本 3.1 发送消息 3.1.1 功能分析 对于这种简单的脚本,需要的功能不多.涉及的一些命令很常见,下面了解脚本所需的几个 ...

  5. SHELL 脚本编程基础

    目录 前言 一. shell 概述 1.1 shell 和 shell 脚本 1.1.1 什么是shell 1.1.2 shell的作用 1.1.3 shell脚本是什么 1.1.4 shell脚本能 ...

  6. Linux shell 脚本编程-实战篇(二)

    继: Linux shell 脚本编程-实战篇(一) 2. 创建与数据库.Web及电子邮件相关的脚本 2.1 MySQL 数据库 2.1.1 MySQL 数据库安装 到 http://repo.mys ...

  7. 《Linux命令行与shell脚本编程大全 第3版》Shell脚本编程基础---34

    以下为阅读<Linux命令行与shell脚本编程大全 第3版>的读书笔记,为了方便记录,特地与书的内容保持同步,特意做成一节一次随笔,特记录如下: 转载于:https://www.cnbl ...

  8. 《Linux命令行与shell脚本编程大全 第3版》Shell脚本编程基础---02

    以下为阅读<Linux命令行与shell脚本编程大全 第3版>的读书笔记,为了方便记录,特地与书的内容保持同步,特意做成一节一次随笔,特记录如下: 转载于:https://www.cnbl ...

  9. 《Linux命令行与shell脚本编程大全 第3版》Shell脚本编程基础---20

    以下为阅读<Linux命令行与shell脚本编程大全 第3版>的读书笔记,为了方便记录,特地与书的内容保持同步,特意做成一节一次随笔,特记录如下: 转载于:https://www.cnbl ...

  10. 《Linux命令行与shell脚本编程大全 第3版》Shell脚本编程基础---43

    以下为阅读<Linux命令行与shell脚本编程大全 第3版>的读书笔记,为了方便记录,特地与书的内容保持同步,特意做成一节一次随笔,特记录如下: 转载于:https://www.cnbl ...

最新文章

  1. ora-01033:oracle initialization or shutdown in progress 解决方法
  2. 系统调用002 KiSystemService函数逆向分析
  3. 链表笔试题汇编(一)
  4. 虚函数表 对C++ 了解的人都应该知道虚函数
  5. php现实的九九乘法,php趣味编程 - php 输出九九乘法
  6. QT实现可移动和改变尺寸的无边框窗口
  7. CSDN markdown编辑器 页面内跳转目录
  8. 实现弹出窗口并转到另一个页面
  9. etcher制作mac启动盘_如何在Mac上创建和引导Linux USB驱动器
  10. docker+MySQL+读写分离
  11. 11.性能之巅 洞悉系统、企业与云计算 --- 云计算
  12. 统计一个数字在排序数组中出现的次数。
  13. BZOJ5219[Lydsy2017省队十连测] 最长路径
  14. Oracle的expdp导出、impdp导出命令
  15. dw1510_超低温种子储存柜
  16. List集合排序总结
  17. 深度解读 AlphaGo 算法原理
  18. 这15个Java多线程面试题及回答你确定不来看看!
  19. HTML计算平均成绩,access计算平均值取整
  20. php获取拼音首字母排序,php 如何获取字符串拼音首字母 - strtoupper

热门文章

  1. K-Means优缺点
  2. Linux系统重要日志文件
  3. python老齐_python-basic
  4. 编写爬虫遇到的问题总结
  5. 【Codeforces Round #546 (Div. 2) E】Nastya Hasn't Written a Legend【线段树】
  6. LaTeX报错 Difference (2) between bookmark levels is greater (hyperref) than one, level fixed.
  7. gitlab mysql 坑_gitlab迁移和踩坑
  8. mysql删除的方法_mysql三种删除方式
  9. Laravel 生态圈
  10. 通过银行卡号,识别相应的银行信息