shell基础

什么是 shell ?

Shell是一个命令解释器,它的作用是解释执行用户输入的命令及程序等,用户输入一条命令, Shell 就解释执行一条。
这种从键盘一输入命令,就可以立即得到回应的对话方式,被称之为交互的方式。 Shell存在于操作系统的最外层,负责直接与用户对话,把用户的输入解释给操作系统,并处理各种各样的操作,
系统的输出结果,输出到屏幕返回给用户,当我们输入系统用户名和密码,登录到 Linux 后的所有操作都是由Shell 解释并执行的。

什么是 shell 脚本?

当命令或程序语句不在命令行下执行,而是通过一个程序文件执行时,该程序就被称为 Shell 脚本。
如果在 Shell 脚本里内置了很多条命令、语句及循环控制,然后一次性把这些命令执行完,这种通过文件执行脚本的方式,称为非交互的方式。
Shell 脚本类似于 DOS 系统下的批处理程序。用户可以在 Shell 脚本中敲入一系列的命令及命令语句组合。
这些命令、变量和流程控制语句等有机地结合起来就形成了一个 Shell 脚本。 # 示例:清除/var/log下messages日志文件的Shell脚本(含命令、变量和流程控制语句)
#!/bin/bash LOG_DIR=/var/log
ROOT_UID=0 # 第一步:必须是 root 用户才能执行脚本,否则给出提示并终止脚本运行 if [ "$UID" -ne "$ROOT_UID" ] # $UID 是系统变量
then
echo "only root user can run this script"
exit 1
fi # 第二步:成功切换到目录 /var/log ,否则给出提示并终止脚本运行
cd $LOG_DIR || { # || 的作用:前面的命令执行失败了,则执行后面的操作
echo "change dir failed"
exit 1
} # 第三步:清理日志 /var/log/message ,清理成功,给出正确提示
cat /dev/null>messages && { # && 的作用:前面的操作执行成功了,再执行后面的操作
echo "Logs cleaned up."
exit 0
} # 第四步:清理失败,给出相应提示
echo "Logs cleaned up failed"
exit 1

Shell脚本在Linux运维工作中地位

Shell脚本语言很擅长处理纯文本类型的数据,而Linux系统中几乎所有的配置文件、日志文件(如NFS、Rsync、Httpd、Nginx、LVS、MySQL等),以及绝大多数的启动文件都是纯文本类型的文件。自然学好Shell脚本语言,就可以利用它在Linux系统中发挥巨大的作用。

Shell脚本语言和3P语言对比

Shell脚本语言的优势在于处理偏操作系统底层的业务,例如:Linux系统内部的很多应用,对于一些常见的企业业务,使用Shell开发会更简单快速,例如:让软件一键自动化安装、优化,监控报警脚本,软件启动脚本,
日志分析脚本等,虽然PHP/Python语言也能够做到,但是,考虑到掌握难度、开发效率、开发习惯等,它们可能就不如用Shell脚本语言流行及有优势了。对于一些常规的业务应用,使用Shell更符合Linux运维简单、易用、
高效的三大基本原则。 PHP语言:
PHP是网页程序语言,也是脚本语言。是一款更注于Web页面开发(前端展示)的语言,例如:wordpress、dedecms、discuz等著名开源产品都是用PHP语言开发的。 Perl语言:
Perl脚本语言,语法灵活、复杂,缺点是不易读,团队协作困难,存世的大量相关程序软件(比如,xtrabackup热备工具、MySQL MHA集群高可用软件等都有Perl语言的身影)。 Python语言:
Python是当下流行的语言,不但可以用于脚本程序开发,也可实现Web程序开发(例如:CMDB管理系统),还可以做软件开发( OpenStack)、游戏开发、大数据开发、移动端开发。

shell脚本的注释

#号后面表示注释

# 多行注释:
# 方式1:
插入注释:
按CTL+v(win下面ctrl+q)进入列模式;
按大些“I”进入插入模式,输入注释符“#”或者是"//",然后立刻按下ESC(两下) 取消注释:
Ctrl + v 进入块选择模式,选中你要删除的行首的注释符号,注意// 要选中两个,选好之后按d即可删除注释 # 方式2:
把需要注释的代码放到 :<<EOF...EOF 中,如下所示:
:<<EOF
echo "hello world"
echo "hello world"
EOF # 方式2 的原理:冒号在shell里面也是命令,表示什么都不做 # 方式3:
把需要注释的代码放到 cat >/dev/null<<EOF...EOF 中,如下:
cat >/dev/null<<EOF
echo "hello world"
echo "hello world"
EOF

Shell脚本的执行

# 方式1. bash script name 或 sh script name
这是当脚本文件本身没有可执行权限(即文件权限属性x位为 - 号)时常使用的方法,或者脚本文件开头没有指定解释器时需要使用的方法(推荐) # 方式2. path/script name 或 ./script name
指在当前路径下执行脚本(脚本要有执行权限),需要先将脚本文件的权限改为可执行(即文件权限属性加 x),具体方法为 chmod +x script name 。然后通过脚本绝对路径或相对路径就可以直接执行脚本了。 # 方式3. source script name 或 . script name # 方式4. sh <script name 或 cat scripts name|sh # 示例:关闭开机自启动的程序
chkconfig --list|grep 3:on|awk '{print "chkconfig",$1,"off"}'|bash # 非循环的方法 # Shell脚本执行过程及父子Shell知识和互相调用 # 登陆一个命令行时,就相当于开启了一个 shell
# 示例
[root@m01 scripts]# cat test.sh
user=`whoami` # 运行这个脚本时,`whoami` 会执行,即把 root 赋值给 user 变量
[root@m01 scripts]# sh test.sh # 此时的 sh test.sh 相当于 新开启了一个 shell (子shell),即在一开始登陆的shell下新开启了一个子shell
[root@m01 scripts]# echo $user # 这个 shell 是你一开始登陆时的 shell (父shell)
# 一开始登陆的 shell 中找不到 user 这个变量的值
[root@m01 scripts]# source test.sh # 当 source 执行一个脚本时,这个脚本相当于是在当前 shell 下运行(即一开始登陆的shell),即此时没有开启新的shell
[root@m01 scripts]# echo $user
root # 经过 source test.sh 之后,echo $user 就会有输出
[root@m01 scripts]# cat call_test.sh
sh test.sh # 在 call_test.sh 中又执行了一个新的子shell
echo $user
[root@m01 scripts]# sh call_test.sh # sh call_test.sh 执行了一个新的子shell
# call_test.sh 这个子shell 无法调用 test.sh 这个子shell中的变量(test.sh的shell相当于call_test.sh shell的子shell)
[root@m01 scripts]# cat call_test.sh
source ./test.sh # 利用 source 或 . 能让 test.sh 和 call_test.sh 在同一个shell下面执行脚本
echo $user
[root@m01 scripts]# sh call_test.sh
root # 利用 source 或 . 就能让 call_test.sh 中 shell 获取到 test.sh 的shell 中的内容
[root@m01 scripts]# OLDBOY=oldboy # 在一开始登陆的shell中定义一个变量 OLDBOY
[root@m01 scripts]# cat call_parent.sh
echo $OLDBOY # 在 call_parent.sh 的 shell 中调用父shell中的变量 OLDBOY
[root@m01 scripts]# sh call_parent.sh
# 无法调用 父shell 中的变量
[root@m01 scripts]# source call_parent.sh # 利用 source 也能让 子shell调用父shell 中的变量
oldboy
[root@m01 scripts]# # 使用 source 或 . 来执行脚本,相当于在同一个shell下面执行脚本,此时变量可以相互调用;
# bash 或 sh 来执行脚本,会开启一个新的 shell (一个子shell,父shell调用不了子shell中的变量) # 父shell和子shell的概念:
在脚本A中运行的脚本B就称为脚本A的子shell, A 是 B 的父shell;
父shell和子shell之间默认不能互相调用

shell执行流程图:

Shell脚本的编程规范和习惯

1. 开头加脚本解释器
2. 附带作者及版权信息
3. 脚本扩展名为 sh
4. 脚本存放在固定的目录下
5. 脚本中不用中文
6. 成对的符号一次书写完成
7. 循环格式一次性输入完成

shell 变量:

默认情况下,在bash Shell 中是不会区分变量是什么类型的,例如:常见的变量类型为整数、字符串、小数等。
变量可分为两类:环境变量(全局变量)和普通变量(局部变量)。环境变量也可称为全局变量,可以在创建他们的 Shell 及其派生出来的任意子进程 Shell 中使用,环境变量又可分为自定义环境变量和 bash 内置的环境变量。
普通变量也可称为局部变量,只能在创建他们的Shell 函数或 Shell 脚本中使用。普通变量一般由开发者在开发脚本程序时创建。 (1) 环境变量
# 显示环境变量:
1、echo $变量名字
2、env
3. set # 定义环境变量:(定义变量时 = 两边不能有空格)
# 3种方法
环境变量尽量大写,环境变量全局生效。
#方式1:
export OLDBOY=1 # 方式2:
OLDGIRL=2
export OLDGIRL # 方式3: declare -x
declare -x A=1 # 上面3种方法是临时定义环境变量,想要永久定义环境变量,可修改 /etc/profile 文件
[root@web01 scripts]# tail -1 /etc/profile
export OLDBOY=1
[root@web01 scripts]# . /etc/profile
[root@web01 scripts]# echo $OLDBOY
1 # 环境变量取消: unset 环境变量名称
unset OLDBOY # 环境变量的文件:
全局文件
/etc/profile
/etc/bashrc
用户环境变量文件
~/.bashrc
~/.bash_profile # 环境变量初始化与对应文件生效顺序:(即环境变量文件生效顺序的优先级)
/etc/bashrc > ~/.bashrc > ~/.bash_profile > /etc/profile # 登录shell时,优先/etc/profile,然后加载~/.bash_profile ,再次加载~/.bashrc,最后加载/etc/bashrc (越往后的文件,生效的优先级越高)
# 建议环境变量放在 /etc/bashrc 中 (2)普通变量
当前用户或者脚本中生效,离开当前用户或者脚本就会失效。
# 变量名:
规则:字母、数字、下划线,3者组合,以字母开头。
要求:见名知意
格式:
1)OldboyAge=1
2)oldboy_age=1
3) oldboyAge=1 ###驼峰语法 # 变量内容:
字符串:
变量名=value # 不加引号。 ## 解析变量或者命令,然后输出;纯数字选择不加引号。
变量名=’value’ # 加单引号。 ## 所见即所得
变量名=”value” # 加双引号。 ## 解析变量或者命令,然后输出;自己定义字符串变量时可默认选择双引号;会把要定义的内容作为一个整体。 命令变量
变量名=`ls`
变量名=$(ls) # 普通变量总结:
针对变量名:
1)变量名的定义要有一定的命令规范,并且要见名知意 OldboyAge=1 ,推荐使用驼峰语法。
2)变量名仅能使用字母、数字、下划线中的任意多个字符,并且要字母开头。 针对变量内容:
3)在脚本中定义普通字符串变量,尽量把变量的内容用双引号括起来。
4)单纯数字的变量内容可以不加引号。
5)希望变量的内容原样输出需加单引号。
6)希望变量值引用命令并获取命令的结果就用反引号或 $() 。 针对赋值符号:
7)变量定义使用赋值符号 (=),赋值符号两端不要有空格。 针对变量输出:
8)使用或者输出变量的内容,可用 $变量名,例如 :echo $OldboyAge 。
9)若变量 (db) 后面有其他字符连接的时候,就必须给变量名 加上大括号 {},例如: $db_t 就要改成 ${db}_t # 特殊位置变量:
$0 获取脚本的名字,如果脚本前面跟着路径的话,那就获取路径加上脚本名字。
[root@m01 scripts]# cat test.sh
echo $0
[root@m01 scripts]# pwd
/server/scripts
[root@m01 scripts]# sh test.sh
test.sh
[root@m01 ~]# sh /server/scripts/test.sh
/server/scripts/test.sh # $0 企业应用:
一般在启动脚本的结尾会使用$0获取脚本的路径和名字给用户提示用;如 /etc/init.d/crond 中:
echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}" $1,$2 --- $n
$1表示脚本后的第一个参数
$2表示脚本后的第二个参数
...
超过$9时,要想获取到后面的参数时,就要加上{},如 ${10}
企业应用:
case "$1" in # 启动脚本的参数
start)
rh_status_q && exit 0
$1
;;
stop) $# 表示脚本后面所有参数的总个数
企业应用:
[root@web01 scripts]# cat test.sh
#!/bin/bash
if [ $# -ne 2 ] # 获取参数的总个数
then
echo "Usage:$0 arg1 arg2"
exit 1
fi
echo ok $* 获取脚本的所有参数,格式为: "$1 $2 $3" (即所有参数为一个整体)
$@ 获取脚本的所有参数,格式为: "$1" "$2" "$3" (每个参数都是一个单独的个体)
# 应用场景:当需要接收脚本后面所有参数时,但是又不知道参数个数就用这两个变量。 区别:
[root@m01 test]# cat test.sh
#!/bin/bash for arg1 in "$*"
do
echo $arg1
done echo ---------------------
for arg2 in "$@"
do
echo $arg2
done
[root@m01 test]# sh test.sh "I am" neo coder.
I am neo coder.
---------------------
I am
neo
coder. # shell进程特殊状态变量:
$? 表示获取上一个命令的返回值,如果返回值为0就证明上一个命令执行正确,非0,就证明上一个命令执行失败的。如下:
echo $? $$ 表示获取当前执行脚本的进程号。如下:
[root@m01 test]# cat test2.sh
#!/bin/bash
echo $$|tee /tmp/a.log # tee 的作用:让 echo 输出,同时也让输出的结果打印到一个 log中
sleep 100
[root@m01 test]# sh test2.sh & # & 的作用表示后台进行
[1] 4695
[root@m01 test]# [root@m01 test]# ps -ef|grep test2.sh
root 4695 3595 0 01:55 pts/2 00:00:00 sh test2.sh
root 4702 3595 0 01:55 pts/2 00:00:00 grep --color=auto test2.sh
[root@m01 test]# cat /tmp/a.log
4695
[root@m01 test]# kill `cat /tmp/a.log` # 通过 $$ 对进程进行管理 $! 表示获取上一个后台工作进程的进程号 $_ 表示获取上一个执行脚本的最后一个参数 # Shell变量子串
${#parameter} ---> 返回变量 $parameter 内容的长度(按字符),也适用于特殊变量
# 应用:查看字符串的长度
[root@m01 ~]# oldboy="I am oldboy"
[root@m01 ~]# echo ${oldboy}
I am oldboy
[root@m01 ~]# echo $oldboy |wc -L
11
[root@m01 ~]# expr length "$oldboy"
11
[root@m01 ~]# echo $oldboy |awk '{print length}'
11
[root@m01 ~]# echo $oldboy |awk '{print length ($0)}'
11 练习题:
I am oldboy I teach linux
打印这些字符串中字符数小于3的单词。
涉及知识点:取字符串长度,for,if。 [root@m01 ~]# echo ${oldboy:3}
m oldboy
[root@m01 ~]# echo ${oldboy:2:2}
am
[root@m01 ~]# echo ${oldboy:3:3}
m o
[root@m01 ~]# OLDBOY=abcABC123ABCabc
[root@m01 ~]# echo ${OLDBOY}
abcABC123ABCabc
[root@m01 ~]# echo ${OLDBOY#a*C}
123ABCabc
[root@m01 ~]# echo ${OLDBOY##a*C}
abc
[root@m01 ~]# echo ${OLDBOY%a*C}
abcABC123ABCabc
[root@m01 ~]# echo ${OLDBOY%a*c}
abcABC123ABC
[root@m01 ~]# echo ${OLDBOY%%a*c} [root@m01 ~]# [root@m01 ~]# OLDBOY="I am oldboy oldboy"
[root@m01 ~]# echo ${OLDBOY}
I am oldboy oldboy
[root@m01 ~]# echo ${OLDBOY/oldboy/oldgirl}
I am oldgirl oldboy
[root@m01 ~]# echo ${OLDBOY//oldboy/oldgirl}
I am oldgirl oldgirl
[root@m01 ~]# ${parameter:-word} 表示如果 parameter 变量值为空或未赋值,就会返回 word 字符串替代变量的值。 [root@m01 ~]# result=${test:-UNSET}
[root@m01 ~]# echo $result
UNSET
[root@m01 ~]# echo $test [root@m01 ~]#

shell变量执行顺序:

shell特殊变量:

shell变量子串:

Bash编程常见运算命令汇总

# 只适合整数运算:
1、(()) 推荐
2、let 次推荐
3、expr
4、$[]
5、declare -i # 既适合整数,又适合小数运算:
1、bc
2、awk 推荐 示例:
############# 整数 ############### # 1、(()) 推荐
[root@m01 ~]# a=1
[root@m01 ~]# b=2
[root@m01 ~]# a=$b+1 # 此时 $b+1 并不会进行数值上的相加
[root@m01 ~]# echo $a
2+1
[root@m01 ~]# a=$((b+1)) # 把要计算的内容用 (()) 括起来,就能进行数值上的运算
[root@m01 ~]# echo $a
3
[root@m01 ~]# echo $((b+3))
5
[root@m01 ~]# echo 2**3
2**3
[root@m01 ~]# echo $((2**3))
8
[root@m01 ~]# echo $((5/3))
1
[root@m01 ~]# echo $((1+2**3-5/3))
8
[root@m01 ~]# echo $((1+2**3-5%3))
7
[root@m01 ~]# ((i++)) # i 自加1,前面不用加 $符号
[root@m01 ~]# echo $i
2
[root@m01 ~]# ((i++))
[root@m01 ~]# echo $i
3 # 2、let 次推荐
[root@m01 ~]# a=2
[root@m01 ~]# i=$a+1
[root@m01 ~]# echo $i
2+1
[root@m01 ~]# let i=$a+1 # let 用来运算
[root@m01 ~]# echo $i
3 # 3、expr用于运算(expr做运算时,运算符号两边必须都有空格)
[root@m01 ~]# expr 50 / 30
1
[root@m01 ~]# expr 1 + 2
3
[root@m01 ~]# expr 2 \* 3 # expr 在进行乘法时,要先将 * 进行转义
6
[root@m01 ~]# expr 2 '*' 3 # expr 乘法时,也可给 * 加上引号
6 # 4、$[]
[root@m01 ~]# echo $[2+ 3]
5
[root@m01 ~]# echo $[2*2]
4 # 5、declare -i
[root@m01 ~]# declare -i a=3+4
[root@m01 ~]# echo $a
7 ############### 小数 #################
# 1、 bc
[root@m01 ~]# echo 1+2|bc # 通过 | 给 bc
3
[root@m01 ~]# echo 1.3+2.5|bc # 能进行小数的运算
3.8
[root@m01 ~]# echo 5/3|bc
1 # 2、 awk (推荐使用awk)
[root@m01 ~]# echo 2.1 1.4|awk '{print $1-$2}'
0.7
[root@m01 ~]# echo 2.1 1.4|awk '{print $1*$2}'
2.94
[root@m01 ~]# echo 2.1 1.4|awk '{print $1/$2}'
1.5
[root@m01 ~]# echo 5 3|awk '{print $1/$2}'
1.66667

expr实战案例:

# 1、 判断一个变量值或字符串是否为整数
# 在shell编程里,由于函数库很少,因此在判断字符串是否为整数时就不是很容易。判断一个字符串是否为整数的方法如下:
# 实现原理:利用以 expr 做计算时必须是整数的规则,把一个变量或字符串和一个已知的整数(非0)相加,看命令返回值是否为0,如果为0,
# 就认为做加法的变量是整数,反之则不为整数 # 示例如下:
[root@m01 scripts]# cat judge_int.sh
#!/bin/bash expr 2 + $1 &>/dev/null # $1 表示接收到的第一个参数; &>/dev/null 表示结果丢到空里面
if [ $? -eq 0 ]
then
echo "$1 is integer"
else
echo "$1 is not integer"
fi
[root@m01 scripts]# sh judge_int.sh 123
123 is integer
[root@m01 scripts]# sh judge_int.sh neo
neo is not integer
[root@m01 scripts]# # 2、 判断文件扩展名是否符合要求
# 补充知识点: expr "变量" : "ReExp" # 可用于匹配; : 两边都要有空格 # 示例如下:
[root@m01 scripts]# cat judge_suffix.sh
#!/bin/bash expr "$1" : ".*\.txt" &>/dev/null # 匹配文件文件;若匹配则返回值为0,反之则为非0
if [ $? -eq 0 ]
then
echo "$1 is text file"
else
echo "$1 is not text file"
fi
[root@m01 scripts]# bash judge_suffix.sh abc.txt
abc.txt is text file
[root@m01 scripts]# bash judge_suffix.sh abc.mp3
abc.mp3 is not text file
[root@m01 scripts]# # 3、 expr length "字符串" ---> 也可用于获取字符串的长度
[root@m01 ~]# OLDBOY="I am oldboy"
[root@m01 ~]# expr length "$OLDBOY"
11
[root@m01 ~]#

bash内置核心命令read

# 变量的赋值:
# 1. 定义法: 如 a=1
# 2. 传参法: 如 $1、$2 等
# 3. read读入: 即读取用户输入
-p 提示
-t 等待用户输入的时间 # read 示例:
[root@m01 ~]# read -t 5 -p "pls input a integer:" # -t 表示超时时间
...
[root@m01 ~]# read -t 5 -p "pls input a integer:" OLDBOY # 用户输入的变量赋值给了 OLDBOY;OLDBOY前面一定要有空格,而且 OLDBOY前不能有 $
pls input a integer:1
[root@m01 ~]# echo $OLDBOY
1
[root@m01 ~]# # read读入的作用: 和用户交互
# 示例如下:
[root@m01 scripts]# cat read_cal.sh
#!/bin/bash #read -t 30 -p "pls input the value of a:" a
#read -t 30 -p "pls input the value of b:" b read -p "pls input two integers:" 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))"
echo "a%b=$((a%b))" [root@m01 scripts]# bash read_cal.sh
pls input two integers:4 6
a+b=10
a-b=-2
a*b=24
a/b=0
a**b=4096
a%b=4
[root@m01 scripts]# # read的企业应用:
[root@m01 scripts]# cat read_pratice.sh
#!/bin/bash cat <<EOF # 输入追加
1. install lamp # 菜单
2. install lnmp
3. exit
EOF
[root@m01 scripts]# sh read_pratice.sh
1. install lamp
2. install lnmp
3. exit
[root@m01 scripts]# cat read_pratice.sh
#!/bin/bash cat <<EOF
1. install lamp
2. install lnmp
3. exit
EOF read -p "pls input an integer from above:" num # 1. 判断是否为数字
expr 2 + $num &>/dev/null
if [ $? -ne 0 ]
then
echo "Usage:$0 {1|2|3}"
exit 1
fi # 判断执行处理
if [ $num -eq 1 ]
then
echo "install lamp..."
elif [ $num -eq 2 ]
then
echo "install lnmp..."
elif [ $num -eq 3 ]
then
echo "bye."
exit # 退出脚本
else
echo "Usage:$0 {1|2|3}"
exit 1
fi
[root@m01 scripts]# sh read_pratice.sh
1. install lamp
2. install lnmp
3. exit
pls input an integer from above:1
install lamp...
[root@m01 scripts]# sh read_pratice.sh
1. install lamp
2. install lnmp
3. exit
pls input an integer from above:3
bye.
[root@m01 scripts]# sh read_pratice.sh
1. install lamp
2. install lnmp
3. exit
pls input an integer from above:4
Usage:read_pratice.sh {1|2|3}
[root@m01 scripts]# sh read_pratice.sh
1. install lamp
2. install lnmp
3. exit
pls input an integer from above:abmvdo
Usage:read_pratice.sh {1|2|3}
[root@m01 scripts]#

条件表达式

通常,在bash的各种条件结构和流程控制结构中都要进行各种测试,然后根据测试结果执行不同的操作,有时也会与if等条件语句相结合,
来完成测试判断,减少程序运行的错误。
执行测试条件表达式后通常会返回“真”或“假”,就像执行命令后的返回值为0表示真,非0表示假一样 语法1: test 测试表达式
语法2: [ 测试表达式 ] #两端有空格
语法3:[[ 测试表达式 ]] #两端有空格
语法4:((测试表达式)) #不需要空格 语法5:(命令表达式)
语法6:`命令表达式` # 条件表达式的编程语法:
[ 测试表达式 ] && 命令1
# 如果前面表达式成功,那么就执行后面命令。 [ 测试表达式 ] || 命令1
# 如果前面表达式失败,那么就执行后面命令。 [ 测试表达式 ] && {
命令1
命令2
命令3
}
# 如果前面表达式成功,那么就执行后面命令。 [ 测试表达式 ] && 命令1 || 命令2
# 如果前面表达式成功,那么就执行命令1,否则执行命令2(相当于一个if...else...语句),如下:
if [ 测试表达式 ]
then
命令1
else
命令2
fi [ 测试表达式 ] && {
命令1
命令2
}||{
命令3
命令4
}
# 如果前面表达式成功,那么就执行命令1,2,否则执行命令3,4。 # 示例如下:
[root@m01 ~]# [ -d /etc/hosts ] && echo "is directory" || echo "not directory" # -d --> 是否存在且为目录
not directory
[root@m01 ~]# [ -d /etc ] && echo "is directory" || echo "not directory"
is directory
[root@m01 ~]# [ -e /etc/host ] && echo "exist" || echo "not exist" # -e --> 是否存在
not exist
[root@m01 ~]# [ -e /etc/hosts ] && echo "exist" || echo "not exist"
exist
[root@m01 ~]# [ -r /etc/hosts ] && echo readable || echo "not readable" # -r --> 是否可读
readable
[root@m01 ~]# [ -x /etc/hosts ] && echo "executable" || echo "not executalbe" # -x --> 是否可执行; 是否可读、可执行等的依据是看文件属性的
not executalbe
[root@m01 ~]# [ -s /etc/hosts ] && echo "file size not 0" || echo "file size is 0" # -s --> 文件大小不为0,则返回真(返回值为0)
file size not 0 文件测试表达式:
为什么需要文件测试表达式?
操作一个对象,就要看对象条件是否满足,否则不要操作。
1、常见功能
2、实践
3、企业应用:启动脚本中的应用。 # 字符串测试表达式:
[ -n "字符串" ] # 字符串长度[不]为0,表达式为真。 not zero。
[ -z "字符串" ] # 字符串长度为0,表达式为真。 zero。
[ "字符串1" == "字符串2" ] # 两个字符串相同则为真。
[ "字符串1" !== "字符串2" ] # 两个字符串不相同则为真。 注意:
1、字符串要用双引号
2、等号可以用一个或者两个。
3、=号两端必须要有空格。 # 示例如下:
[root@m01 ~]# [ -n "neo" ] && echo "length not zero" || echo "length zero"
length not zero
[root@m01 ~]# [ -z "neo" ] && echo "length is zero" || echo "length is not zero"
length is not zero
[root@m01 ~]# char="neo"
[root@m01 ~]# [ -n "$char" ] && echo "length not zero" || echo "length zero"
length not zero
[root@m01 ~]# unset char
[root@m01 ~]# [ -n "$char" ] && echo "length not zero" || echo "length zero"
length zero
[root@m01 ~]# # 应用示例:
[root@m01 scripts]# cat read_cal.sh
#!/bin/bash read -p "pls input two integers:" a b # 1. 先判断是否输入了两个参数
[ -z "$b" ] &&{ # 如果变量b没有值,则输入的变量数量一定是不够2个
echo "pls input two args"
exit 1
} # 判断输入的变量是否为数字
expr $a + $b + 1 &>/dev/null
if [ $? -ne 0 ]
then
echo "Usage:$0 arg1 and arg2 must be integers"
exit 1
fi # 3. 进行运算
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@m01 scripts]# bash read_cal.sh
pls input two integers:
pls input two args
[root@m01 scripts]# bash read_cal.sh
pls input two integers:1
pls input two args
[root@m01 scripts]# bash read_cal.sh
pls input two integers:ab 1
Usage:read_cal.sh arg1 and arg2 must be integers
[root@m01 scripts]# bash read_cal.sh
pls input two integers:2 3
a+b=5
a-b=-1
a*b=6
a/b=0
a**b=8
a%b=2 # 整数测试表达式:
# 示例如下:
[root@m01 scripts]# [ 1 -eq 1 ] && echo "equal" || echo "not equal"
equal
[root@m01 scripts]# [[ 1 > 2 ]] && echo "greater than" || echo "less than"
less than
[root@m01 scripts]# (( 3>2 )) && echo "greater than" || echo "less than"
greater than
[root@m01 scripts]# [[ 1 -gt 2 ]] && echo "greater than" || echo "less than"
less than # 整数表达式的应用:
# 使用 read 的交互式方式,来比较两个整数的大小
# 分析如下:
1、2个数
2、整数
3、比较大小
大于
等于
小于 [root@m01 scripts]# cat compare_int.sh
#!/bin/bash
read -p "pls input two integers:" a b # 1. 必须至少是两个参数
[ -z "$b" ] &&{
echo "pls input at least two integers"
exit 1
} # 2. 两个参数得是整数
expr $a + $b + 1 &>/dev/null
if [ $? -ne 0 ]
then
echo "two args must be integers"
exit 2
fi # 3. 比较大小
[ $a -gt $b ] && {
echo "$a > $b"
exit 0
}
[ $a -eq $b ] &&{
echo "$a == $b"
exit 0
}
#[ $a -lt $b ] &&{
# echo "$a < $b"
# exit 0
#} echo "$a < $b"
[root@m01 scripts]# bash compare_int.sh
pls input two integers:a
pls input at least two integers
[root@m01 scripts]# bash compare_int.sh
pls input two integers:1 b
two args must be integers
[root@m01 scripts]# bash compare_int.sh
pls input two integers:1 5
1 < 5
[root@m01 scripts]# # 逻辑测试表达式:
# 示例如下:
[root@m01 scripts]# [ 1 -eq 2 -a -f /etc/hosts ] && echo "all are true" || echo "not all are true" # -a 连接两个测试条件
not all are true
[root@m01 scripts]# [ 1 -eq 2 -o -f /etc/hosts ] && echo "at least one is true" || echo "all are false"
at least one is true
[root@m01 scripts]# [ ! 1 -eq 2 ] && echo 1 || echo 0 # ! ---> 取反
1
[root@m01 scripts]#

文件测试表达式的常见功能说明:

字符串测试表达式的常见功能说明:

整数测试表达式知识:

逻辑测试表达式:

不同符号测试表达式[ ] 、 [[ ]] 、 (( ))、test的区别:

Linux(15):shell 编程的更多相关文章

  1. Linux 下shell 编程学习脚手架

    linux body { font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 1.6; padding-t ...

  2. Linux下Shell编程

    Linux的shell编程 1.什么是shell? 当一个用户登录Linux系统之后,系统初始化程序init就为每个用户执行一个称为shell(外壳)的程序. shell就是一个命令行解释器,它为用户 ...

  3. 【Hadoop离线基础总结】linux的shell编程

    linux的shell编程 基本了解 概述 Shell是一个用C语言编写的程序,通过shell用户可以访问操作系统内核服务,它类似于DOS下的command和后来的cmd.exe.Shell既是一种命 ...

  4. linux中shell编程

    shell编程 1 echo -e 识别\转义符 \a \b \t \n \x十六进制 \0八进制 等等 #!/bin/bash echo -e "hello world" 执行脚 ...

  5. linux下shell编程示例-获取进程id

    今天初步学习了一下linux下的shell编程,简单记录一下测试用例 1.编辑shell脚本文件如下: #!/bin/bashecho "hello bash linux"echo ...

  6. linux之shell编程基本语法

    Shell是用户与内核进行交互操作的一种接口,目前最流行的Shell称为bash Shell.Shell也是一门编程语言<解释型的编程语言>,即shell脚本<就是在用linux的s ...

  7. Linux学习——shell编程之变量

    shell编程之变量:Linux shell编程基础中的变量. 包括Bash变量的分类和各变量的详细使用,如:用户自定义变量.环境变量.语系变量.位置参数变量和预定义变量. 1:什么是Bash变量? ...

  8. 3. Linux的shell编程

    Shell 是一个用 C 语言编写的程序, 通过 Shell 用户可以访问操作系统内核服务.它类似于 DOS 下的 command 和后来的 cmd.exe.Shell 既是一种命令语言,又是一种程序 ...

  9. Linux之shell编程的基本使用

    1.Shell shell是一个命令行解释器,它为用户提供了一个向 Linux 内核发送请求以便运行程序的系统级程序 2.shell编程打印hello world 2.1 代码部分 #!/bin/ba ...

  10. Linux学习——shell编程之正则表达式和字符处理命令

    shell编程之正则表达式 一 正则表达式 1 什么是正则表达式 正则表达式用于描述字符排列和匹配模式的一种语法规则.它主要用于字符串的模式分隔.匹配.查找及替换操作. 2 shell编程之正则表达式 ...

随机推荐

  1. 遍历PspCidTable枚举进程

    //测试环境:win7 32位 1 // DriverEntry.cpp #include "ntddk.h" #include <ntddvol.h> #includ ...

  2. debug1: expecting SSH2_MSG_KEX_ECDH_REPLY解决

    设置mtu ifconfig en1 mtu 1200 代理工具 退出lantern,退出shadowsocks

  3. 从汇编看c++中的多态

    http://www.cnblogs.com/chaoguo1234/archive/2013/05/19/3079078.html 在c++中,当一个类含有虚函数的时候,类就具有了多态性.构造函数的 ...

  4. 万事先问『为什么』 what why how

    万事先问『为什么』! 遇到问题时,很多人的行为模式顺序是,先问『做什么』,『怎么做』,他们从来不问『为什么』,他们对根源性问题很模糊. 而聪明人则是先问『为什么』,再去构建『怎么做』,而『做什么』就是 ...

  5. Robot Framework(十三) 执行测试用例——创建输出

    3.5创建输出 执行测试时会创建几个输出文件,并且所有这些文件都与测试结果有某种关联.本节讨论创建的输出,如何配置它们的创建位置以及如何微调其内容. 3.5.1不同的输出文件 输出目录 输出文件 日志 ...

  6. Scrapy-架构

    Scrapy架构(各组件的功能)及Scrapy引擎控制数据流的过程 1. Scrapy架构图(绿线是数据流向): □ Scrapy引擎(Engine):引擎负责控制数据流在系统的所有组件中流动,并在相 ...

  7. 关于highchts X时间轴比设置时间相差好几个小时的解决

    经过一番查询和研究发现,在曲线图里,x轴的UNIX时间戳是要乘以1000的(通过在线的UNIX转换,结果与原来没有乘以1000的时间戳相差甚远),不然显示的时间会有很大的误差,真是百思不得其解. 另外 ...

  8. C-基础:表达式中存在有符号类型和无符号类型时,都自动转换为无符号类型

    void foo(void) { unsigned ; ; (a+b > ) puts("> 6") : puts("<= 6"); } 答案 ...

  9. ios 登录功能学习研究

    登录功能是我在湖畔做的第一个需求. 当时PD给我的草图和下图类似: (图片来自知乎iOS客户端登录界面) 不过需求中要求用户名或者密码错误时,输入框要抖动(类似Mac登录密码错误的抖动效果). 如果实 ...

  10. 关于JS的继承总结

    最近都在巩固JS的基础知识,今天组要看的是有关继承方面的,每次看都会加深自己的理解呢 1.借助构造函数实现继承 原理:在子类中改变父类this的指向 function Parent1() { this ...