Shell 基础介绍 [1]

本文目录
1.什么是Shell?
2.脚本语言类型
3.其他常用的脚本语句种类
4.Shell脚本的建立和执行
5.Shell 变量类型
6.普通变量
7.Shell 特殊重要变量
8.Shell进程状态变量
9.Parameter Expansion
10.扩展:其他变量的替换
11.变量的数值(整数)计算
↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑

1.什么是Shell?

Shell是一个命令解释器,它在操作系统的最外层,负载直接与用户对话,把用户的输入解释给操作系统,并处理各种各样的操作系统的输出结果,输出到屏幕并返回给用户。这种对话方式可以是交互的方式(从键盘输入命令,可以立即得到shell的回应),或非交互式(执行脚本程序)的方式。
图解:
当linux命令或语句不在命令行下执行(严格说,命令行执行的语句也是shell脚本),而是通过一个程序文件执行时,该程序就被称为shell脚本或shell程序,shell程序很类似DOS系统下的批处理程序。这些命令、变量和流程控制语句结合起来就形成了一个功能强大的shell脚本。

简单的小脚本

  #!/bin/bash# 清除日志脚本, 版本 2LOG_DIR=/var/logROOT_UID=0     # $UID为0的时候,用户才具有root用户的权限
# 要使用root用户来运行,因此,对当前用户进行判断,不合要求给出友好提示,并终止程序运行。if["$UID"-ne "$ROOT_UID"]
thenecho "Must be root to run this script."exit 1
  fi
# 如果切换到指定目录不成功,给出提示,并终止程序运行。
cd $LOG_DIR ||{echo "Cannot change to necessary directory.">&2exit 1}
# 经过上述两个判断后,此处的用户权限和路径就应该是对的了,只有清空成功,才打印成功提示。cat /dev/null > messages &&{
echo "Logs cleaned up."exit 0  # 退出之前返回0表示成功. 返回1表示失败。
}
echo "Logs cleaned up fail."exit 1
1.必须是root才能执行脚本,否则给出友好提示并终止程序运行
2.成功切换目录(cd/var/log),否则给出友好提示并终止运行
3.清理日志(cat /dev/null >messages)清理成功,给出正确提示
4.给出相应提示(echo 输出)

Shell脚本语言擅长处理纯文本类型的数据,而linux系统中几乎所有的配置文件、日志文件(如nfs、rsync、httpd、nginx、lvs等)、绝大多数启动文件纯文件。就可以利用它在Linux系统中发挥巨大的作用。

2.脚本语言类型

2.1 Shell脚本语言的种类

在UNIX/LINUX中主要由两大类shell
1.Bourne shell(包括sh、ksh、bash)
Bourne shell (sh)
Korn shell (ksh)
Bourne Again shell (bash)
POSIX shell (sh)
2. Cshell (包括csh、tcsh)
C shell (csh)
TENEX/TOPS C shell (tcsh)
Shell脚本语言是弱类型语言,较为通用的shell有标准的Bourne shell (sh)和C shell (csh)。其中Bourne shell (sh)已经被bash shell取代,但是我们还是习惯称之为sh。
 查看Centos6 系统SHELL情况:
[root@web02 ~]# cat /etc/shells 
/bin/sh  <==黄色标记为重点
/bin/bash
/sbin/nologin
/bin/dash
/bin/tcsh
/bin/csh
Linux系统中的主流shell是Bash,它是Bourne Again Shell的缩写,Bash是由Bourne Shell(sh)发展而来的,但Bash与sh稍有不同,它还包含了csh和ksh的特色,但大多数脚本可以不加修改地在sh上运行

3.其他常用的脚本语句种类

3.1 PHP

PHP是网页程序,也是脚本语言。是一款更专注于web页面开发(前端展示)的脚本语言,例如:Dedecms,discuz。PHP程序也可以处理系统日志,配置文件等,php也可以调用系统命令。

3.2 Perl

Perl脚本语言。比shell脚本强大很多,语法灵活、复杂,实现方式很多,不易读,团队协作困难,但仍不失为很好的脚本语言,存世大量的程序软件。MHA高可用Perl写的

3.3 Python

Python,不但可以做脚本程序开发,也可以实现web程序以及软件的开发。近两年越来越多的公司都会要求会Python。

Shell脚本与php/perl/python语言的区别和优势?

shell脚本的优势在于处理操作系统底层的业务(linux系统内部的应用都是shell脚本完成)因为有大量的linux系统命令为它做支撑。2000多个命令都是shell脚本编程的有力支撑,特别是grep、awk、sed等。例如:一键软件安装、优化、监控报警脚本,常规的业务应用,shell开发更简单快速,符合运维的简单、易用、高效原则
PHP、Python优势在于开发运维工具以及web界面的管理工具,web业务的开发等。处理一键软件安装、优化,报警脚本。常规业务的应用等php/python也是能够做到的。但是开发效率和复杂比用shell就差很多了。

常用操作系统的默认shell

1.Linux是Bourne Again shell(bash)
2.Solaris和FreeBSD缺省的是Bourne shell(sh)
3.AIX下是Korn Shell(ksh)
4.HP-UX缺省的是POSIX shell(sh)
提示:比较常用和充电的是Bourne Again shell(bash)

查看Centos默认bash?

[root@db01 ~]# echo $SHELL
/bin/bash
[root@db01 ~]# echo shell
shell
[root@db01 ~]# grep root /etc/passwd
root:x:0:0:root:/root:/bin/bash
修改创建用户默认配置文件路径
[root@db01 ~]# cat /etc/default/useradd 
# useradd defaults file
GROUP=100
HOME=/home
INACTIVE=-1
EXPIRE=
SHELL=/bin/bash
SKEL=/etc/skel
CREATE_MAIL_SPOOL=yes

Shell脚本的建立和执行

1.1 shell脚本的建立

在Linux系统中,shell脚本(bash shell程序)通常是在编辑器(vi/vim)中编写,由Unix/Linux命令、bash shell命令、程序结构控制语句和注释等内容组成。
vi = 记事本
vim =编辑器emeditor、editplus notepad++
我们可以制作一个vi=vim的别名
[root@db01 ~]# alias vi='vim'  
[root@db01 ~]# vim /etc/profile
export alias 'vi=vim'
[root@db01 ~]#./etc/profile

1.2 脚本开头(第一行)

一个规范的shell脚本在脚本第一行会指出由那个程序(解释器)来执行脚本中的内容,这一行内容在linux bash编程中一般为:
#!/bin/bash
or
#!/bin/sh <==255字符以内
其中开头的”#!”字符又称为幻数,在执行bash脚本的时候,内核会根据”#!”后的解释器来确定该用那个程序解释这个脚本中的内容。注意:这一行必须在每个脚本顶端的第一行,如果不是第一行则为脚本注释行。
[root@web02 tmp]# cat 1.sh
#!/bin/bash
echo "123"
#!/bin/sh  <==代表注释
echo "456"
 sh和bash的区别
早期的Bash与sh稍有不同,它还包含了csh和ksh的特色,但大多数脚本都可以不加修改地在sh上运行
[root@web02 /]# ll /bin/sh 
lrwxrwxrwx.1 root root 4May  104:26/bin/sh -> bash
[root@web02 /]# ll /bin/bash 
-rwxr-xr-x 1 root root 941720Jul24  2015/bin/bash
企业面试题案例一:Centos Linux系统默认的shell是()
解答:bash
查看方法1:
[root@web02 ~]# echo $shell
bash
[root@web02 ~]# echo $SHELL
/bin/bash
查看方法2:
[root@web02 ~]# grep root /etc/passwd
root:x:0:0:root:/root:/bin/bash
提示:结尾的/bin/bash就是shell解释器

1.3 脚本注释

在shell脚本中,跟在(#)井号后面的内容表示注释,用来对脚本进行注释说明,注释部分不会被当做程序执行,仅仅给用户看,系统解析器是看不到,更不会执行。
特别提示:注释尽量不使用中文

1.4 Shell脚本的执行

当shell脚本运行时,它会先查找系统环境变量ENV,改变量指定了环境文件(通常是~./bashrc,~./bash_profile,/etc/bashrc,/etc/profile等)然后从该环境变量文件开始执行脚本,当读取了ENV的文件后,shell才会开始执行shell脚本中的内容
特殊技巧:设置crond任务时,最好把系统环境变量在定时脚本中重新定义,否则,一些系统环境变量不会被夹在。
 Shell 脚本的执行通常可以采用以下几种方式:
1.bash script-name或sh script-name(推荐使用)
2.path/script-name或./script-name(当前路径下执行脚本)
###<==此项需要脚本有执行权限
3.source script-name 或. script-name #<==注意”.”点号和后面字符之间有空格。
4.sh <script-name 或 cat script-name|sh(同样适合bash)
全路径执行如果不加命令全路径会没有权限
/server/scripts/abc.sh 权限不够
/bin/sh /server/scripts/abc.sh  可以执行
提示:
第三种方法通常是使用source或者”.”点号读入或加载指定的shell脚本文件(如san.sh),然后,依次执行指定shell脚本文件san.sh 中的所有语句。这些语句将作为当前父shell脚本运行。
source或者”.”点号命令的功能是在当前shell中执行source或者”.”点号加载并执行相关脚本文件中的命令以及语句,而不是产生一个字shell来执行命令文件中的命令。
脚本里面的内容是无法和外面的变量沟通,但是外面的变量在脚本里面是可以引用的。
如果想在脚本里面的变量引用到命令行需要使用source or .

Shell 变量类型

变量可以分为两类:环境变量(全局变量)和普通变量(局部变量)。
环境变量也可称为全局变量,可以在创建他们的Shell及其派生出来的任意子进程shell中使用,环境变量又可分为自定义环境变量和Bash内置的环境变量
普通变量也可称为局部变量,只能在创建他们的Shell函数或Shell脚本中使用。普通变量一般是由开发者用户开发脚本程序时创建的。

环境变量

环境变量一般用于定义Shell的运行环境,保证Shell命令的正确执行,Shell通过环境变量来确定登录用户、命令路径、终端类型、登录目录等,所有的环境变量都是系统全局变量,可用于所有子进程,这包括编辑器,Shell脚本和各类应用(crond任务必须比较特殊)
环境变量可以在命令行中设置创建,但用户退出命令行时这些变量值就会丢失,因此,如果希望永久保存环境变量,可在用户家目录下的.bash_profile或.bashrc文件中或全局配置/etc/bashrc/或/etc/profile 文件或者/etc/profile.d中定义。将环境变量放入上述的文件中,每次用户登录时这些变量值都将被初始化一次
有一些环境变,比如HOME、PATH、UID、USER等,在用户登陆之前就已经被/bin/login 程序设置好了。通常环境变量定义保存在用户家目录下的.bash_profile文件或者全局的配置文件/etc/profile中。

查看系统变量
env命令,也可以使用set (显示的没有env变量多)
[root@www ~]# env
HOSTNAME=www
TERM=linux
SHELL=/bin/bash
HISTSIZE=1000
SSH_CLIENT=125.34.74.615169622
SSH_TTY=/dev/pts/0
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:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;31:*.bz2=01;31:*.tbz=01;31:*.tbz2=01;31:*.bz=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=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:*.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:
MAIL=/var/spool/mail/root
PATH=/application/mysql/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin:/root/bin
PWD=/root
LANG=en_US.UTF-8
HISTCONTROL=ignoredups
SHLVL=1
HOME=/root
LOGNAME=root
CVS_RSH=ssh
SSH_CONNECTION=125.34.74.6151696120.25.167.4222
LESSOPEN=|/usr/bin/lesspipe.sh %s
G_BROKEN_FILENAMES=1
_=/bin/env

自定义环境变量

        设置环境变量

如果想设置环境变量,就要给在变量赋值之后或设置变量时使用export命令。带-x选项的declare内置命令也可完成同样的功能。
格式:
1.export变量名=value
2.变量名=value;export变量名
3.declare-x 变量名=value
提示:以上为三种设置环境变量的方法
例:
export NAME=oldboy
declare -x NAME=oldboy
NAME=oldboy;export NAME

让环境变量永久生效的常用设置文件及区别

1、用户的变量变量配置:
[root@www ~]# ls /root/.bashrc 
/root/.bashrc
[root@www ~]# ls /root/.bash_profile 
/root/.bash_profile
提示:用户的环境变量设置常见的为用户家目录下的.bashrc和.bash_profile
2、全局环境变量的配置
全局环境的配置文件常见的配置文件为
  1. /etc/profile
  2. /etc/bashrc
  3. /etc/profile.d
需要登陆后初始化或显示加载内容可以把脚本文件放在/etc/profile.d下,设置可执行即可
3、生产环境 自定义JAVA环境鞭炮配置实例
环境变量知识小结:
1、变量名通常要大写
2、变量可以在自身的shell以及子shell中使用。
3、通过export来定义环境变量
4、输出用$变量名,取消用unset变量名
5、书写定时任务要注意环境变量,最好在执行的shell脚本中重新定义。
6、如果系统永久生效可以放在用户环境变量文件或全局环境变量文件里。

1.1 普通变量

1.1.1 定义本地变量

本地变量在用户当前的Shell生存期的脚本中使用。例如,本地变量OLDBOY取值为bingbing,这个值在用户当前Shell生存期中有意义。如果在Shell中启动另一个进程或退出,本地变量值将无效
1. 普通变量定义****
变量名=value    #<==赋值时不加引号
变量名=’value’  #<==赋值时加单引号
变量名=”value”  #<==赋值时加双引号
2.Shell中定义变量名及给变量内容赋值的要求
变量名一般是由字母、数字、下划线组成,可以字母或下划线开头
abc,abc123,abc_123
变量的内容可以使用单引号或双引号引起来,也可不加引号,但是这三者是不同的。
3. 普通变量定义及输出的不同例子
[root@web02 ~]# a=1
[root@web02 ~]# b='2'
[root@web02 ~]# c="3"
[root@web02 ~]# echo "$a"
1
[root@web02 ~]# echo "$b"
2
[root@web02 ~]# echo "${c}"
3
提示:$变量名表示输出变量,可以用$c和${c}两种用法
小结:连续普通字符串内容赋值给变量,不管用什么引号或者不用引号,它的内容是什么,打印变量就输出什么
4.例子2
[root@db01 scripts]# a=192.168.1.2
[root@db01 scripts]# b='192.168.1.2'
[root@db01 scripts]# c="192.168.1.2"
[root@db01 scripts]# echo "a=$a"
a=192.168.1.2
[root@db01 scripts]# echo "b=$b"
b=192.168.1.2
[root@db01 scripts]# echo "c=${c}"
c=192.168.1.2
============================================
[root@db01 scripts]# a=192.168.1.2-$a
[root@db01 scripts]# b='192.168.1.2-$a'
[root@db01 scripts]# c="192.168.1.2-$a"
[root@db01 scripts]# echo "a=$a"
a=192.168.1.2-192.168.1.2
[root@db01 scripts]# echo "b=$b"
b=192.168.1.2-$a
[root@db01 scripts]# echo "c=${c}"
c=192.168.1.2-192.168.1.2-192.168.1.2
小结:数字内容变量定义可不加引号,其他没有特别要求的字符串等定义最好都加上双引号,确实真的需要原因输出的的就加单引号

1.2 把一个命令的结果作为变量的定义方法

获取命令结果的变量内容写法常见的有两种:
变量名=`ls`         #<==命令用反引号引起来
变量名=$(ls)       #<==命令用$()括起来

自定义普通字符串变量

(1)内容是纯数字,简单连续字符(内容中不带任何空格)此时定义方式可以不加任何引号
a.OldboyAge=33
b.NETWORD=yes
(2)没特殊情况时,字符串一律用双引号定义,特别是多个字符串中间由空格时
a.NFS_MODULE="no load"
b.MyName="Good game"
(3)当变量里内容需要原样输出时,要用单引号”,这样的需求极少
a.HOST_NAME=’OCALHOST’
提示:
1、变量名只能为字母、数字、下划线,只能以字母或下划线开头
2、规范的命令名写法要见名如意。
1)OldboyAge=1  #每个单词的首字母大写
2)oldboy_age=1#单词之间用“_”
3)oldboyAgeSex=1#驼峰语法:首个单词的首字母小写,其余单词首字母大写
4)OLDBOY=1#单词全大写

1.3 变量定义的完整小结:

(1)普通变量内容的定义:
1.连续的数字或字符串,可以不加引号,例如a=123
2.变量内容很多,还希望解析变量,就加双引号,例如a=”/etc/rc.local $USER”,会对内容中的USER解析输出
3.希望原样输出就用单引号,例如:a=’$USER’
(2)希望编译内容是命令得解析结果的定义:
1.反引号括起来,例如:a=`ls`
2.或者$()括起来,例如:a=$(ls)
(3)变量的输出方法:
使用$变量名输出变量内容,常用echo $变量名

1.4 变量定义的小结技巧:

1、注意命令变量定义前后的字符“ 例如”CMD=`ls`”
2、在变量名前加$,可以取得该变量的值,使用echo或printf命令可以显示变量的值,$A和${A}的写法不同,但功能是一样的。
3、用echo等命令输出变量的时候,也有单引号、双引号、反引号的形式。
4、$dbname_tname,若变量后面有其他字符连接的时候,就必须给变量加上大括号{}
例如:$dbname_tname就要改写成${dbname}_tname
5、养成所有字符串变量用双引号括起来使用的习惯,将会减少很多编程时遇到的问题。
有关shell变量定义及变量输出单引号、双引号不加引号的简要说明如下

名称

解释

单引号

所见即所得,输出时会将单引号内的所有内容都原样输出。

双引号

把双引号内的所有内容输出出来:如果内容中有命令(要反引)变量特殊字符等,会先把变量、命令解析出来,然后在输出最终内容来。

无引号

把内容输出出来,会将含有空格的字符串视为一个整体输出,

反引号

一般用于引用命令,执行的时候命令会被执行,相当于$()

1.5 特殊例子:awk调用shell变量引号例子

[root@db01 scripts]# ETT=123
[root@db01 scripts]# awk 'BEGIN {print "$ETT"}'
$ETT
[root@db01 scripts]# awk 'BEGIN {print '$ETT'}'
123
[root@db01 scripts]# awk 'BEGIN {print $ETT}'
一道实用linux运维问题的9种shell解答方法(http://oldboy.blog.51cto.com/2561410/760192)

Shell 特殊重要变量

1.1 Shell特殊位置变量
$0 获取当前执行的shell脚本文件名,如果执行脚本带路径那么久包括脚本路径。
$n 获取当前执行的shell脚本的第n个参数值。如果n大于9,需要用大括号括起来${10}
$* 获取当前shell脚本的所有传参的参数,将所有的字符视为单个字符,相当于”$1$2$3$4″
$# 获取当前执行的shell脚本后面接的参数的总个数
$@ 这个程序的所有参数 “$1” “$2” “#3″,这是将参数传递给其他程序的最佳方式,因为他会保留所有内嵌在每个参数里的任何空白,”$@”和”$*”都要加双引号
提示:$*和$@了解即可
$*和$@的区别例子
1.$* 将命令行脚本所有参数视为单个字符串,等同于”$1$2$3″,”$*“ 要用双引号
2.$@将命令行脚本每个参数视为单独的字符串,等同于”$1″ “$2” “$3″这是将参数传递给其他程序的最佳方式,因为他会保留所有的内嵌在每个参数里的任何空白.
[root@web02 /]#for i in "$*";do echo $i;done
##在有双引号的情况下"$*"参数里引号内容当做一个参数输出了!
I am oldboy
[root@web02 /]#for i in "$@";do echo $i;done
##在有双引号的情况下,每个参数以独立的内容输出。
I am 
oldboy
其他:linux下set和eval的使用小案例精彩解答(特殊位置变量用法)

http://oldboy.blog.51cto.com/2561410/1175971

范例1:$n的实践例子
[root@web02 /]# cat p.sh 
#!/bin/bash
echo $1
[root@web02 /]# sh p.sh good         #传一个字符串参数
good
[root@web02 /]# sh p.sh good good    #传2个字符串参数,第二个不会接受,$1只显示第一个
good
[root@web02 /]# sh p.sh "good good"  #加引号括起来表示为一个字符串参数
good good
测试 26的英文字符
  1. [root@db01 scripts]# cat q.sh   
  2. echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} $12 $13 $14 $15
  3. [root@db01 scripts]# sh q.sh {a..z}
  4. a b c d e f g h i j k a2 a3 a4 a5
提示:脚本里面的$1就是我们执行的第一个参数,例如/etc/init.d/iptables stop  其中stop相当于$1
$0案例
[root@db01 scripts]# cat q.sh                  
echo $"Usage: $0 {start|stop}"
[root@db01 scripts]#/server/scripts/q.sh start
Usage:/server/scripts/q.sh {start|stop
$1 脚本传参的第一个参数,以此类推
$0 脚本的名字以及路径
$# 脚本传参的参数数量
例子:$?  
$? 返回值
0 表示成功
 [root@db01 scripts]# cat q.sh 
#!/bin/sh
. /etc/init.d/functions
if [ $# -ne 1 ]
thenecho $"Usage: $0 {start|stop}"exit 1
fi
rsync --daemon
if [ $? -eq 0 ]
thenaction "oldboy" /bin/true
fi
exit 1 脚本的返回值,此处的exit 1 可以随便定义。如果定义为1 $?返回的值就是1
return 1 函数的返回值

Shell进程状态变量

$$ 获取当前shell脚本的进程号(PID)
$! 执行上一个指令的PID
$? 获取上一个指令的返回值(0为成功,非0为失败)
$_ 在此之前执行的命令或脚本的最后一个参数
提示:查找知道方法:man bash,然后搜索Special Parameters.

 范例2:应用案例:当系统中只能有某个脚本同时只能运行一个进程的时候。
[root@oldboy day2]# cat pid.sh 
#!/bin/sh
pidpath=/tmp/a.pid
if [ -f "$pidpath" ] 
  then kill -USR2 `cat $pidpath` >/dev/null 2>&1rm -f $pidpath
fi
echo $$ >$pidpath
sleep 300
bash内置命令(没有路径(二进制文件))
alias
break
cd
continue
declare
echo
eval
exec
exit
export
help
history
jobs
kill
let
local
logout
printf
pwd
read
readonly
return
set
shift
times
trap
typeset
ulimit
umask
unalias
unset
常用操作如下表:man bash找本节资料“Parameter Expansion
${#string}                         返回$string的长度
${string:position}                 在$string中,从位置$position之后开始提取子串
${string:position:length}          在$string中,从位置$position之后开始提取长度为$length的子串
${string#substring}                从变量$string开头开始删除最短匹配$substring子串
${string##substring }              从变量$string开头开始删除最长匹配$substring子串
${string%substring}                从变量$string结尾开始删除最短匹配$substring子串
${string%%substring}               从变量$string结尾开始删除最长匹配$substring子串
${parameter/pattern/string}        使用string,来代替第一个匹配的pattern
${parameter/#pattern/string}       从开头匹配string变量中的pattern,使用string来替换匹配的pettern
${parameter/%patter/string}        从结尾开始匹配string变量中的pattern,就用string来替换匹配pattern
${parameter//pattern/string}       使用string,来代替所有匹配的pattern
更多资料man bansh 查找“Parameter Expansion”

获取变量字符串的长度
[root@db01 ~]# OLDBOY="I am oldboy"
[root@db01 ~]# echo $OLDBOY
I am oldboy
[root@db01 ~]# echo $OLDBOY|wc -L
11
[root@db01 ~]# echo ${#OLDBOY}
11
[root@db01 ~]# expr length "$OLDBOY"
  1. 11
截取OLDBOY变量字符串从第2个字符之后开始取,默认取后面字符的全部,第二个字符不包含在内。也可以理解为删除前面多少个字符。
[root@web02 /]# OLDBOY="I am oldboy linux,welcome to our training."
[root@web02 /]# echo $OLDBOY
I am oldboy linux,welcome to our training.
[root@web02 /]# echo ${OLDBOY:2}
am oldboy linux,welcome to our training.
截取OLDBOY变量字符串从第二个字符之后开始取,取2个字符
[root@web02 /]# echo ${OLDBOY:2:2}
am
提示:类似于cut -c参数;
[root@web02 /]# echo ${OLDBOY}|cut -c 1-4
I am
[root@web02 /]# echo ${OLDBOY}|cut -c 3-4
am
从变量$OLDBOY开头删除最短匹配”a*C”子串
[root@web02 /]# OLDBOY=abcABC123ABCabc
[root@web02 /]# echo ${OLDBOY#A*c}
abcABC123ABCabc
[root@web02 /]# echo ${OLDBOY#a*c}
ABC123ABCabc
[root@web02 /]# echo ${OLDBOY#a*C}
123ABCabc
[root@web02 /]# echo ${OLDBOY##a*c}
  1. [root@db01 ~]# OLDBOY="I am oldboy"
  2. [root@db01 ~]# echo ${OLDBOY/oldboy/oldgirl}
  3. I am oldgirl
  4. [root@db01 ~]# OLDBOY="I am oldboy oldboy"  
  5. [root@db01 ~]# echo ${OLDBOY/oldboy/oldgirl}
  6. I am oldgirl oldboy
小结:
#是开头删除匹配最短
##是开头删除匹配最长
%是结尾删除匹配最短
%%是结尾删除匹配最长

生产案例:

httpd=${HTTPD-/usr/sbin/httpd}
prog=httpd
pidfile=${PIDFILE-/var/run/httpd/httpd.pid}
lockfile=${LOCKFILE-/var/lock/subsys/httpd}
RETVAL=0
STOP_TIMEOUT=${STOP_TIMEOUT-10}
企业场景例子:尽量不要使用rm
  1. [root@MySQL test]# cat del.sh
  2. path=/server/backup
  3. find ${path:=/tmp/} -name "*.tar.gz" -type f |xargs rm -f
  4. ===================
  5.  path=/server/backup
  6. find ${path:=/tmp/} -name "*.tar.gz" -type f |xargs rm -f
  7. [root@MySQL test]# cat del.sh
  8. path=/server/backup
  9. find ${path:=/tmp/} -name "*.tar.gz" -type f |xargs rm -f
  10. [root@MySQL test]# sh -x del.sh
  11. + path=/server/backup
  12. + find /server/backup -name '*.tar.gz' -type f
  13. + xargs rm -f
  14. [root@MySQL test]# sed -i '1d' del.sh
  15. [root@MySQL test]# cat del.sh
  16. find ${path:=/tmp/} -name "*.tar.gz" -type f |xargs rm -f
  17. [root@MySQL test]# sh -x del.sh
  18. + find /tmp -name '*.tar.gz' -type f
  19. + xargs rm -f
  20. #rm -fr ${path:=/tmp/}

扩展:其他变量的替换

变量替换表:了解,man bash查到资料Parameter Expansion

变量的数值(整数)计算

    变量的数值计算常见的有如下几个命令:
(())、let、expr、bc(小数)、$[],其他都是整数。
如果要执行简单的整数运算,只需将特定的算术表达式用”$((“和”))” 括起来即可。
shell的算术运算符号常置于”$((“……”))”的语法中。这一语法如同双引号的功能

1)(())用法:(此方法很常用)

范例:shell的算术运算实例如下:
[root@db01 ~]# ((a=1+2**3-4%3))
[root@db01 ~]# echo $a
8
[root@db01 ~]# ((a=1+2**3-4%3))
[root@db01 ~]# echo $a
8
[root@db01 ~]# echo $((1+2**3-4%3))
8
记忆方法:++,–
变量a在前,表达式的值为a,然后a自增或自减,变量a在符号后,表达式值自增或自减,然后a值自增或自减
[root@db01 ~]# a=$((100*(100+1)/2)) 
[root@db01 ~]# echo $a
5050

范例6:这是一个实践考试题,内容如下:

把a,b两个变量通过命令行脚本传参的方式实现上面混合运算脚本的功能
第一种方法:
#!/bin/bash
a=6
b=2
echo "a-b =$(( $a - $b ))"
echo "a+b =$(( $a + $b ))"
echo "a*b =$(( $a * $b ))"
echo "a/b =$(( $a / $b ))"
echo "a**b =$(( $a ** $b ))"
echo "a%b =$(( $a % $b ))"
第二种方法:
[root@web02 ~]# cat abc.sh
#!/bin/bash
a=$1
b=$2
echo "a-b =$(( $a - $b ))"
echo "a+b =$(( $a + $b ))"
echo "a*b =$(( $a * $b ))"
echo "a/b =$(( $a / $b ))"
echo "a**b =$(( $a ** $b ))"
echo "a%b =$(( $a % $b ))"

2)let命令的用法(整数)

格式:
let 赋值表达式
【注】let赋值表达式功能等同于:((赋值表达式))
范例1:给自变量i加8
[root@db01 scripts]# i=2    
[root@db01 scripts]# let i=i+8
[root@db01 scripts]# echo $i  
10 

3)expr (evaluate(求值)expressions(表达式))命令的用法:

expr命令一般用于整数值,但也可用于字符串,用来求表达式变量的值,同时expr也是一个手工命令计算器
1.计算
语法:expr Expression
[root@web02 /]# expr 2+2
4
[root@web02 /]# expr 2-2
0
[root@web02 /]# expr 2*2
expr: syntax error  语法错误
[root@web02 /]# expr 2 \* 2
4
[root@web02 /]# expr 3/2
1
[root@web02 /]# expr 3%2
1
另一种玩法
[root@db01 scripts]# i=0
[root@db01 scripts]# i=`expr $i + 1`
[root@db01 scripts]# echo $i
1 
expr $[$a+$b] 表达式形式,其中$a $b 可为整数值
[root@web02 /]# expr $[2+3]
5
[root@web02 /]# expr $[2*3]
6
[root@web02 /]# expr $[2**3]        2的2次方*3
8
[root@web02 /]# expr $[2/3]
0
[root@web02 /]# expr $[2%3]
2
四种运算方法:
1.(())
2.let
3.expr
4.[]
整数
判断一个文件的扩展名是不是pub  (发送公钥的命令就是使用此参数)
 #!/bin/sh
if expr "$1" : ".*\.pub" &>/dev/null
  then echo "you are using $1"
elseecho "pls use *.pub file"
fi 
[root@web02 ~]# sh aaa.sh oldboy
pls use *.pub file
[root@web02 ~]# sh aaa.sh oldboy.pub
you are using oldboy.pub
STRING : REGEXP
              anchored pattern match of REGEXP in STRING

判断一个输入是不是数字

 #!/bin/sh
while true
doread  -p "Pls input:" aexpr $a + 0 >/dev/null 2>&1[ $? -eq 0 ] &&echo int||echo chars
done
如果判断是不是数字,就执行错误shars
[root@db01 scripts]# cat b.sh 
#!/bin/sh
expr $1 + 1 >/dev/null 2>&1
[ $? -eq 0 ] &&echo int||echo chars
[root@db01 scripts]# sh b.sh  1
int
[root@db01 scripts]# sh b.sh  1a
chars
[root@db01 scripts]# sh b.sh  100
int
[root@db01 scripts]# sh b.sh  100abc
chars

expr match 整数判断

[[ `expr match "$a" "[0-9][0-9]*$"` == 0 ]] && {echo "the first is not a num"exit 3
}

计算变量长度

[root@db01 scripts]# a="oldboy"
[root@db01 scripts]# expr length "$a"
6

expr功能

1.整数计算
2.判断扩展名
3.判断输入是否为整数
4.计算变量的长度
[root@db01 scripts]# bc
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'. 
1+1
2
1+3
4
6*8
48
另一种使用bc的方式
[root@db01 scripts]# echo 1+2|bc
3
[root@db01 scripts]# echo 8-2|bc
6
inux下的bc命令可以设置结果的位数,通过 scale.
[root@db01 scripts]# echo "scale=3;5.23 / 3.13"|bc
1.670
[root@db01 scripts]# echo "scale=2;5.23 / 3.13"|bc 
1.67
比如:
$ echo "scale=4; 1.2323293128 / 1.1" | bc -l
1.1202
bc命令简单的算法
[root@web02 ~]# i=2
[root@web02 ~]# i=`echo $i+1|bc`
[root@web02 ~]# echo $i
3
可以做加法计算
[root@web02 ~]# echo 3.5+5
3.5+5
[root@web02 ~]# echo 3.5+5|bc
8.5
减法计算
[root@web02 ~]# echo 3.5-5|bc
-1.5
乘法计算
[root@web02 ~]# echo 3.5*5|bc
17.5
保留位数(bc的用处不大)
[root@web02 ~]# echo "scale=2; 3.5*5.1"|bc
17.85
[root@web02 ~]# echo "scale=2; 3*5"|bc
15
[root@web02 ~]# echo "scale=1; 3*5"|bc
15
提示:bc是特有的小数计算
awk也可以进行小数计算
[root@web02 ~]# echo "5.5 5.6" |awk '{print ($2-$1)}'
0.1
[root@web02 ~]# echo "5.5 5.5" |awk '{print ($2+$1)}'
11
范例:通过一条命令计算输出1+2+3+…+10的表达式,并计算出结果,使用bc计算
输出内容如:1+2+3+4+5+6+7+8+9+10=55
第一种方法:
[root@web02 ~]# seq -s "+"" "10
1+2+3+4+5+6+7+8+9+10
[root@web02 ~]# echo `seq -s "+"" "10`=`seq -s "+"" "10|bc`
1+2+3+4+5+6+7+8+9+10=55
第二种方法:
[root@web02 ~]# echo {1..10}|tr " ""+"
1+2+3+4+5+6+7+8+9+10
[root@web02 ~]# echo `echo {1..10}|tr " ""+"`=`echo {1..10}|tr " ""+"|bc`
1+2+3+4+5+6+7+8+9+10=55
更多方法:因计算不是重点,所以我们不重点研究。
特点:bc的独有特点是支持小数运算,当然也可以整数运算。

typeset命令的用法

使用整数变量进行计算
例如:
[root@web02 ~]# typeset -i A=1 B=3
[root@web02 ~]# A=A+B
[root@web02 ~]# echo $A
4
小结:
shell的数值运算方法:
expr、(())、let、bc、$[]、awk typeset

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/575950.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c++创建二叉树_数据结构:查找(4)|| 平衡二叉树

在介绍平衡二叉树之前&#xff0c;应该先了解平衡因子的概念&#xff0c;平衡因子定义为左子树深度减去右子树深度&#xff0c;这个值的绝对值越大&#xff0c;非常容易理解它就对应着越不平衡的情况。一棵平衡的二叉树的平衡因子只能是1&#xff0c;0&#xff0c;-1如何构建一…

华睿相机sdk 开发_索尼发布相机远程操作SDK(软件开发工具包)

索尼从2020年12月9日开始&#xff0c;向开发者免费提供针对索尼数码相机的软件开发工具包“ Camera Remote SDK” 1.03版。“ Camera Remote SDK”开发的软件可以远程更改相机设置、并执行诸如快门释放&#xff0c;实时取景监视(如取景和对焦)之类的操作。支持的操作系统包括Wi…

Linux 字体颜色设置

本文主要介绍Linux 字体颜色的调整&#xff0c;常用于shell脚本当中。我们举一个例子&#xff1a;echo-e"\033[44;37;5m ME \033[0m COOL" 以上命令设置背景成为蓝色&#xff0c;前景白色&#xff0c;闪烁光标&#xff0c;输出字符“ME”&#xff0c;然后重新设置屏幕…

利用Unity实现AOP

.NET程序中&#xff0c;可以利用Unity来实现AOP&#xff0c;用来进行日志、缓存或权限的处理。这里我们来写一个简单的程序&#xff0c;让其实现简单的AOP功能。 1.使用NuGet&#xff0c;在项目中获取Microsoft.Practices.Unity。 2.新建一个ITalk类及其实现 public interface …

javascript数组的各种操作

用 js有非常久了&#xff0c;但都没有深究过js的数组形式。偶尔用用也就是简单的string.split(char)。这段时间做的一个项目&#xff0c;用到数组的地方非常多&#xff0c;自以为js高手的自己竟然无从下手&#xff0c;一下狠心&#xff0c;我学&#xff01;呵呵。学了之后才知道…

老男孩Shell企业面试题30道 [答案]

老男孩Shell企业面试题 shell 2016年9月7日 本文来自于老男孩教育,未经本人同意&#xff0c;禁止转载&#xff01;否则追究法律责任。 原文&#xff1a;http://oldboy.blog.51cto.com/2561410/1632876 企业面试题1&#xff1a; &#xff08;生产实战案例&#xff09;&#x…

深度优化LNMP之Nginx [1]

Nginx基本安全优化 1.调整参数隐藏Nginx版本号信息一般来说&#xff0c;软件的漏洞都和版本有关&#xff0c;因此我们应尽量隐藏或清除Web服务队访问的用户显示各类敏感信息&#xff08;例如&#xff1a;Web软件名称及版本号等信息&#xff09;&#xff0c;这样恶意的用户就很难…

5阶无向完全图_运动轿跑风 全新上汽名爵5预告图发布

【太平洋汽车网 新车频道】近日&#xff0c;上汽名爵官方发布了一组全新一代名爵5&#xff08;询底价|查参配&#xff09;的预告图。从图片可以看出&#xff0c;换代而来的全新名爵5采用最新的家族化设计语言&#xff0c;外观风格与新款名爵6较为接近&#xff0c;采用轿跑式溜背…

Shell 企业29道面试题 [转]

企业面试题1&#xff1a;&#xff08;生产实战案例&#xff09;&#xff1a;监控MySQL主从同步是否异常&#xff0c;如果异常&#xff0c;则发送短信或者邮件给管理员。提示&#xff1a;如果没主从同步环境,可以用下面文本放到文件里读取来模拟&#xff1a; 阶段1&#xff1a;开…

深度优化LNMP之Nginx [2]

配置Nginx gzip 压缩实现性能优化 1.Nginx gzip压缩功能介绍 Nginx gzuo压缩模块提供了压缩文件内容的功能&#xff0c;用户请求的内容在发送出用客户端之前&#xff0c;Nginx服务器会根据一些具体的策略实施压缩&#xff0c;以节约网站出口带宽&#xff0c;同时加快了数据传…

go int 转切片_一文掌握GO语言实战技能(二)

Go 数组Go 切片Go 变量和内存地址Go Map 类型Go 面向对象编程Go 方法的定义GO 数组数组是同一类型的元素集合。Go中的数组下标从0开始&#xff0c;因此长度为n的数组下标范围是[0, n-1]。整数数组中元素默认初始化为0&#xff0c;字符串数组中的元素默认初始化为""。…

设置固定长度_加气块砌筑(构造柱、圈梁设置)技术交底21条

墙体砌筑技术交底我给下发21条&#xff0c;内容不全&#xff0c;砌筑的墙体观感差&#xff0c;欢迎大家提出宝贵意见1、填充墙的材料、平面位置尺寸见建筑施工图纸&#xff0c;不得随意更改。2、当首层填充墙下无基础梁或结构梁板时&#xff0c;墙下应做基础&#xff0c;基础作…

深度优化LNMP之MySQL

MySQL数据库优化框架体系 1.硬件层面优化 2.操作系统层面优化 3.MySQL数据库层面优化 4.MySQL安全优化 5.网站集群架构上的优化 6.MySQL流程、制度控制优化 硬件层面优化 1、数据库物理机采购 CPU&#xff1a; 64位CPU&#xff0c;一台机器2-16颗CPU。至少2-4颗&#xff0…

element vue 纵向滑动条_Vue 部分

1、ES6Vue &#xff1a;1、Vue 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是&#xff0c;Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层&#xff0c;不仅易于上手&#xff0c;还便于与第三方库或既有项目整合。另一方面&#xff0c;当与现代化的…

C#集合通论

前言 写这篇文章的最初动力是来自于一次笔试经历。有一道笔试题大概是这样的&#xff1a;程序使用一个txt文件来存储操作记录。存储记录是多行字符串&#xff0c;每一行代表一次操作记录&#xff0c;格式如下&#xff1a;用户名操作事项名称操作时间。现在假设这个txt文件已经非…

Shell 脚本案例实战 [4]

for循环结构for 循环结构语句1.for循环结构&#xff1a;语法&#xff1a;for 变量名 in 变量取值列表do指令…done提示&#xff1a;在此结构中“in 变量取值列表”可省略&#xff0c;省略时相当于in “$”&#xff0c;使用for i 就相当于使用for i in “$”2.C语言型for循环结构…

深度优化LNMP之PHP

PHP缓存加速介绍1.操作码介绍及缓存原理当客户端请求一个php程序时&#xff0c;服务器的PHP引擎会解析该PHP程序&#xff0c;并将其编译为特定的操作码文件&#xff08;Operate Code,opcode&#xff09;该文件是执行PHP代码后的一种二进制表示形式。默认情况下&#xff0c;这个…

PHP服务Fcgi进程及PHP解析优化

1、PHP引擎缓存加速常见四种软件&#xff1a;1.eAccelerator2.Zendcache3.xcache4.apc5.zendopcache php5.5自带2、使用tmpfs作为缓存加速缓存的文件目录 [rootweb02 ~]# mount -t tmpfs tmpfs /dev/shm -o size256m[rootweb02 ~]# mount -t tmpfs /dev/shm/ /tmp/eaccelerator…

电路 晶振频率_都说晶振是电路的心脏,你真的了解它吗?

之所以说晶振是数字电路的心脏&#xff0c;就是因为所有的数字电路都需要一个稳定的工作时钟信号&#xff0c;最常见的就是用晶振来解决&#xff0c;可以说只要有数字电路的地方就可以见到晶振。常见种类我们常说的晶振&#xff0c;包含两种。一种需要加驱动电路才能产生频率信…

ios 数组中的字典排序_利用数组和字典,实现按指定规则的排序

大家好&#xff0c;今日我们继续讲解数组与字典解决方案&#xff0c;今日讲解第47讲&#xff1a;利用字典和数组&#xff0c;实现按指定规则的排序。随着字典讲解的深入,我们发现字典真的很神奇,在VBA代码中,给人以十分清爽的感觉,在这套数组与字典解决方案中,我会尽可能的把经…