Linux 快速学习总结 ( ͡° ͜ʖ ͡° ) 本文档采用 Centos Linux 8.x 学习测试
目录
__ __ _______
/ | / | / \
$$ | $$/ _______ __ __ __ __ $$$$$$$ | ______
$$ | / |/ \ / | / |/ \ / | $$ | $$ | / \
$$ | $$ |$$$$$$$ |$$ | $$ |$$ \/$$/ $$ | $$ |/$$$$$$ |
$$ | $$ |$$ | $$ |$$ | $$ | $$ $$< $$ | $$ |$$ | $$ |
$$ |_____ $$ |$$ | $$ |$$ \__$$ | /$$$$ \ $$ |__$$ |$$ \__$$ |
$$ |$$ |$$ | $$ |$$ $$/ /$$/ $$ | $$ $$/ $$ $$/
$$$$$$$$/ $$/ $$/ $$/ $$$$$$/ $$/ $$/ $$$$$$$/ $$$$$$/
一、Linux 概述
前世今生
Linux 是一种操作系统,它 = 内核 + 其他基础软件
Linux 内核1991年10月,由芬兰大学生 Linus Torvalds 带头开发的操作系统。
1992年Linux 【内核】与 【GNU软件】(将GUNU作为除内核外的其他基础软件)结合,完全自由的操作系统 Linux 正式诞生
。
GNU (计划和自由软件基金会)在1984年由理查德-斯托曼创办,希望开发一个类似UNIX并且是自由软件的完整操作系统,GNU是“GNU’s Not Unix”的递归缩写。创办GNU的缘由很大一部分原因是:之前的Unix操作系统 开始收费和商业闭源了。
其实在20世纪90年代,GNU项目已经开发了诸如 bash shell 程序,gcc系列的编译程序、gdb调试程序等。
完整的Linux操作系统在此GNU的基础上诞生,因此严格意义上说:Linux系统被称为“GNU/Linux”操作系统
。
命令查看Linux版本,总会发现最后一串字符是 “GNU/Linux”
[root@k8s-node2 ~]# uname -a
Linux k8s-node2 4.18.0-193.28.1.el8_2.x86_64 #1 SMP Thu Oct 22 00:20:22 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
[root@k8s-node2 ~]#
1996年 美国机构确认 Linux 1.2.13 符合 POSIX 标准,也就是符合 IEEE里面的标准。
常用的几个版本
Linus Torvalds 只是开发了内核,内核不是完整的操作系统,不管不同版本的Linux系统相似度在90%以上。
内核是一个提供了 设备驱动、文件系统、进程管理、网络管理等功能的系统软件。
Red Hat 版本:商业软件
Ubuntu 版本: 南非人开创 ,是一个以桌面应用为主的操作系统
Debian 版本: 业余爱好者维护更新,快速稳定
CentOS版本:基于Red Hat ,企业级发行版本,是免费软件
SuSE 版本:欧洲比较流行,支持用于自动化测试的OpenQA
二、基本使用
命令的基本格式
一般登录Linux命令行 如下界面:
[root@k8s-node2 ~]#
[ ]
提示符的分隔符号,没有特殊含义root
表示当前用户是谁,现在是root用户@
分隔号,没有特殊含义k8s-node2
表示当前主机名的简称,一般没有经过设计的都会是 localhost~
表示当前所在的目录,~ 是指目前在家目录#
命令提示符 ,超级用户就是’#’ 如果是普通用户则会是 ‘$’ 一般root用户为超级用户
命令格式:
[root@k8s-node2 ~]# 命令 [选项] [参数]
选项 分为短格式 和 长格式 ,短格式是英文缩写,长格式是全单词,两个都是用 “-”开头
下面的两个命令 -a 和 --all 互为等同:
[root@k8s-node2 elk]# ls -a
. .. log logstash
[root@k8s-node2 elk]# ls --all
. .. log logstash
[root@k8s-node2 elk]#
简单命令使用
-
w 和 who 显示当前用户信息,w 可以显示所有连接的用户
[root@k8s-node2 elk]# w 16:21:46 up 230 days, 22:59, 3 users, load average: 0.20, 0.13, 0.10 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT root pts/0 114.82.34.212 14:52 1:29m 15:23m 0.01s -bash root pts/1 114.82.34.212 15:42 39:04 0.01s 0.01s -bash root pts/2 114.82.34.212 16:12 1.00s 0.04s 0.00s w
-
echo 显示打印参数 -e -n 选项
-
date 显示设置日期时间 -s 选项
-
password 设置密码
二进制包RPM
两大主流二进制包:RPM 和 DPKG(Debian Linux使用)
RPM 包的基本格式: 包名-版本号-发布次数.发行商.[Linux平台].适合的硬件平台.包扩展名
例如httpd的RPM包:httpd-2.4.6-40.sl7.1.x86_64.rpm
httpd
: 包名
2.4.6
:版本号
40
:已经发布40次
sl7
:发行商 sl7表示是Red Hat公司发布的在 RHEL7.x或CentOS7.x上使用
x86_64
: 是适用的硬件平台 64位的CPU可以安装
RPM包默认安装的 路径
路径 | 说明 |
---|---|
/etc/ | 配置文件安装目录 |
/usr/bin/ | 可执行的命令安装目录 |
/usr/lib/ | 所使用的函数保存位置 |
/usr/share/doc/ | 使用手册保存位置 |
/usr/share/man/ | 帮助文档保存位置 |
[root@k8s-node2 elk] rpm -ivh 包全名1 包全名2 包全名3
-i 安装
-v 详情
-h 进度
[root@k8s-node2 elk] service 服务名 start|stop|restart|status
[root@k8s-node2 elk] rpm -Uvh 待升级的包全名 -U 不存在则安装
[root@k8s-node2 elk] rpm -Fvh 待升级的包全名 -F 不存在则不升级
[root@k8s-node2 elk] rpm -e 包全名1 卸载包
[root@k8s-node2 elk] rpm -qal 包名 查找包
-l 列出包的所在目录
-p 列出没有安装的包
三、Shell 编程基础
shell 是一个交互式命令解释器,是连接用户或应用程序和内核的连接器。
[root@k8s-node2 ~] cat test.sh
#! /bin/bash
echo "这是一个简单的脚本文件"
echo -n "Enter Your Name:" # -n 不换行,echo默认换行
read name # 从键盘输入
echo "Hello, $name!" #显示信息
#!
说明该脚本是哪一种shell编写的cat /etc/shells
查看那几种shell- 最常见的shell有 Bourne shell(简称 sh)、C shell(简称 csh)、Korn shell(简称 ksh)、Bourne-again Shell(简称 bash)
通配符
常用的通配符一共5个,查找文本经常使用。
符合 | 含义 | 举例 |
---|---|---|
* | 匹配除/之外任意字符0次或多次 | ls a* 列出以a开头的文件名 |
? | 匹配任意单个字符 | d? 表示以d开头的两个字符的文件名 |
[ ] | 匹配里面任意一个字符 | a[bc] 匹配ab或ac, a[1-9] 匹配a1到a9 |
[^ ] 或[! ] | 匹配不在里面的任意一个字符 | [^HW]* 匹配非H或w开头的文件名 |
{str1,str2,str3} | 匹配其中任意一个字符串 | 逗号前后不能有空格 |
引号
shell 中3中引号 单引号、双引号、倒引号
- 单引号里面的所有字符都作为普通字符展示或使用
- 双引号里面的所有字符(除
$
、倒引号
、转义字符"\\
" 除外)都作为普通字符展示或使用 - 倒引号代表引用命令
[root@ecs-s6 ~] export userName=张三
[root@ecs-s6 ~] echo $userName
张三
[root@ecs-s6 ~] echo '刚刚输入的是$userName'
刚刚输入的是$userName
[root@ecs-s6 ~] echo "刚刚输入的是$userName"
刚刚输入的是张三
[root@ecs-s6 ~] today=`date`
[root@ecs-s6 ~] echo ${today}
Mon Aug 30 21:43:54 CST 2021
输入输出重定向
默认情况下 标准输入、输出、错误输出都是以文件的方式存在,通常缩写为 stdin、stdout、stderr
。
标准输入:键盘
标准输出、标准错误输出:屏幕
常用的输入输出重定向符号 > >> <
类型 | 符号 | 作用 |
---|---|---|
标准输入重定向 | command < file | 将文件作为命令的输入 |
command << 分界符 | 从标准输入中读取,直到输入 分界符 结束 | |
标准输出重定向 | command > file | 以覆盖的方式将 command 执行的结果输出到 file中 |
command >> file | 以追加的方式将 command 执行的结果输出到 file中 | |
标准错误输出重定向 | command 2 > file | 以覆盖的方式将 command 执行的错误输出到 file中 |
command 2 >> file | 以追加的方式将 command 执行的错误输出到 file中 |
wc 命令是计算输入的字符 数量或者行数等信息 wc --help 查看,下面是根据标准输入的内容计算行数:
[root@ecs-b208 ~]# wc -l <<END
> 1
> 2
> 3
> 4
> END
4
[root@ecs-b208 ~]#
文件描述符
上面输出重定向完整的写法应该是 command fd > file
其中 fd就是文件描述符,如果不写默认为 1
Linux 一切皆文件,包括 标准输入、输出、错误输出,为了区分各个文件,Linux给每一个文件分配唯一的ID,这个ID是一个整数,被称为文件描述符(File Descriptor)。
一个进程创建时候,Linux为每一个进程自动打开3个标准文件( stdin、stdout、stderr),其文件描述符为0,1,2
下面是 使用ls命令进行查看文件,正确的结果输出到 test.txt , 错误的信息输出到 error-test.txt
[root@ecs-b208 ~] ls | grep "java" 1> test.txt
[root@ecs-b208 ~] cat test.txt
java-8.tar
[root@ecs-b208 ~] ls | grep java nginx 2> error-test.txt
[root@ecs-b208 ~] cat error-test.txt
grep: nginx: No such file or directory
[root@ecs-b208 ~]#
如果希望 正确的信息 或者 错误的信息全部存储到一个文件中可以这样写:
[root@ecs-b208 ~] ls | grep java nginx > all-info.txt 2> all-info.txt
[root@ecs-b208 ~] cat all-info.txt
grep: nginx: No such file or directory
如果希望什么都不要输出,可以指定输出到/dev/null
[root@ecs-b208 ~] ls -al > /dev/null
[root@ecs-b208 ~]
任何放入 /dev/null 中的数据都会被丢弃,不能恢复!
命令连接操作符
多条命令可以在一行中出现, ";" "&&" "||"
符合连接多个命令。
";"
命令是顺序执行,后面的命令不管前面的命令是否正确执行,自己都会依次执行下去
"&&"
只有第一条执行成功了后面才会继续执行 , 比如下面的 cd /opt2 && date 将不会执行date操作
[root@ecs-s6 ~] ls ; date; cd /opt/ ; pwd
certificate.crt fullchain.crt logs nacos private.pem
Mon Aug 30 22:02:44 CST 2021
/opt
[root@ecs-b208 ~] cd /opt2 && date
-bash: cd: /opt2: No such file or directory
[root@ecs-b208 ~] cd /opt2 ; date
-bash: cd: /opt2: No such file or directory
Tue Oct 19 17:42:50 CST 2021
[root@ecs-b208 ~]#
逻辑或“||”
, 前面一条命令执行错误,后面一条命令才能执行,下面是查看目录 tdir是否存在,不存在就创建它
[root@ecs-b208 ~] ls ./tdir || mkdir ./tdir
ls: cannot access ./tdir: No such file or directory
[root@ecs-b208 ~] ls ./tdir/
[root@ecs-b208 ~]#
小括号和大括号
这两个都是将多个shell命令 集合起来,放在一起,逻辑上看成是一条命令。
[root@ecs-b208 ~]#
[root@ecs-b208 ~] (name=zhangsan; echo $name)
zhangsan
[root@ecs-b208 ~] { echo "这是大括号"; who; pwd;
>
> echo "可以换行"
> date
> pwd
> echo "over"; }
这是大括号
root pts/0 2021-10-19 16:59 (124.78.171.204)
/root
可以换行
Tue Oct 19 17:55:17 CST 2021
/root
over
[root@ecs-b208 ~]#
大括号左边的 "{" 后面必须有一个空格,右边的"}" 前面必须有一个 ";" 号
小括号里面的命令在子shell中执行,大括号里面命令在当前shell中执行
其他操作符
-
管道符
采用
“|”
代表,连接两个命令,例如“命令1|
命令2”, 命令1的正确输出
作为命令2的输入信息[root@ecs-b208 /]# date | more Wed Oct 20 10:17:11 CST 2021
-
后台运行命令符
采用
“&”
代表,让当前的命令运行在后台,与用户无交互。[root@ecs-b208 /]# java -jar application.jar &
-
注释符
shell 脚本以“
#
” 开头的正文为单行注释, 第一行以“#!
” 开头后面跟的是shell的绝对路径,指使用哪一种shell
四、Shell编程
变量
用户自定义变量
- 如何定义
直接shell命令行或shell脚本文件中定义, 编写格式 “key=value”
shell中所有的变量值默认都是“字符串”类型
key的命名规则:字母下划线开头,其他部分只能为字母或数字
,一般大写字母的变量为系统变量,因此用户自定义一般小写!
value和=之间不应有空格,如果value首字符为空格,则采用“” 引号包裹value值
[root@ecs-b208 ~]# name=张全蛋
[root@ecs-b208 ~]# name1=" 张2蛋"
- 如何引用
采用 $变量名
符合连接变量名输出
采用 ${变量名}
符合包裹变量名输出,这样可防止出现变量名和其他字符连接出现歧义错误
采用 "$变量名"
符合包裹变量名输出
如果采用小括号包裹变量名
$(变量名)则等同于倒引号
`变量名` ``
[root@ecs-b208 ~]# echo $name
张全蛋
[root@ecs-b208 ~]# echo $name1
张2蛋
[root@ecs-b208 ~]# echo ${name1}
张2蛋
[root@ecs-b208 ~]# echo "${name}"11111
张全蛋11111
[root@ecs-b208 ~]#
数组变量
bash 目前仅支持一维数组,不支持多维数组。
采用"( str1 str2 str3 ... )
" 来表示数组变量,空格作为元素的分割符,元素下标从0开始
${names[*]}
和 ${names[@]}
都表示输出全部元素内容
${names[*]}
会将里面的元素变成一个整体字符串输出
${names[@]}
则逐个输出里面的元素
[root@ecs-b208 ~]# names=(zhangsan lishi wangwu "2 ha")
[root@ecs-b208 ~]# echo ${names}
zhangsan
[root@ecs-b208 ~]# echo ${names[0]}
zhangsan
[root@ecs-b208 ~]# echo ${names[1]}
lishi
[root@ecs-b208 ~]# echo ${names[*]}
zhangsan lishi wangwu 2 ha
[root@ecs-b208 ~]# echo ${names[@]}
zhangsan lishi wangwu 2 ha
[root@ecs-b208 ~]#
系统预定义变量
已经被系统定义好的,不可被用户修改的变量,用户可以直接拿来使用。
预定义变量 | 说明 | 举例 |
---|---|---|
$? | 上一命令返回码,一般情况正常结束返回0 其他返回大于0的整数 | 常用 |
$$ | 当前进程号 PID | |
$! | 上一个后台命令对应的进程号 | 常用 |
$- | 当前运行shell程序的选项 | |
$# | 命令行上的参数个数 | shell脚本中编写函数 |
$* | 命令行给出的所有实参,所有参数看成一个字符串整体 | |
$@ | 命令行给出的所有实参,所有参数看成一个数组 | |
$n | 位置参数变量 $0代表命令本身 $1 代表第一个参数 $2 代表第二个参数,9个以上的参数必须要大括号 ${10} | cat file1 fil2 其中cat 对应 0 f i l e 1 对 应 0 file1 对应 0file1对应! file2 对应 $2 |
[root@ecs-b208 /]# vim fn_add.sh
#! /bin/bash
let num1=$1
let num2=$2
let sum=num1+num2
echo "当前测试参数个数: $#"
echo "取其中传入的 参数1=$1 参数2=$2"
echo "结果为: ${sum}"
[root@ecs-b208 /]# source fn_add.sh 1 2 3
当前测试参数个数: 3
取其中传入的 参数1=1 参数2=2
结果为: 3
[root@ecs-b208 /]#
环境变量
环境变量也是系统预定义变量,环境变量为全局变量,用户自定义变量只在当前shell生效。
使用 env
命令列出已经定义的环境变量。
按环境变量的生存周期来划分,可分为两类:
1、永久的:
在/etc/profile
文件中添加变量【对所有用户生效(永久的)】
在用户目录下的.bash_profile
文件中添加变量【对单一用户生效(永久的)】
2、临时的:
使用export 变量名称=变量值
命令格式声明即可,变量在关闭shell时失效。
常用的系统级环境变量
[root@ecs-b208 /]# echo $HOME
/root
[root@ecs-b208 /]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/usr/local/jdk1.8.0_181/bin:/usr/local/apache-maven-3.6.1/bin:/opt/soft/nginx-1.14.2/sbin:/root/bin
[root@ecs-b208 /]# echo $PS1
[\u@\h \W]\$
[root@ecs-b208 /]# echo ~
/root
变量 | 说明 | 常见用法 |
---|---|---|
$HOME 或 ~ | 当前用户家目录绝对路径 | |
$PATH | shell 查找命令的目录列表 | 安装完毕应用程序,例如java,会在/etc/profile 文件中修改 $PATH 的值,让每一个shell窗口都能执行java的命令 |
$PS1 | shell 主提示符 [\u@\h \W]\$ | \$ 如果是root用户则为 \#, 其他用户为\$ \t 24小时格式 \T 12小时格式\H 完整主机名称\h 主机名称第一个字段\s 所用shell名称\u 当前用户名 |
$PWD | 当前工作目录的绝对路径 | |
$SHELL | 当前使用的哪一种shell |
下面是常见修改 $PATH的场景,安装完毕JDK后,修改/etc/profile 文件尾部,添加永久有效的环境变量
[root@ecs-b208 /]# vim /etc/profile
# /etc/profile 最下面添加如下内容
# PATH格式为:
# PATH=$PATH:<PATH 1>:<PATH 2>:<PATH 3>:------:<PATH N>
export JAVA_HOME=/usr/local/jdk1.8.0_181
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export M2_HOME=/usr/local/apache-maven-3.5.4
# 需要注意的是,最好不要把当前路径”./”放到PATH里,这样可能会受到意想不到的攻击
export PATH=$PATH:$JAVA_HOME/bin:$M2_HOME
[root@ecs-b208 /]# source /etc/profile
数值运算
shell 中所有的变量都是“字符串类型”,请看下面的例子,原本期望得到33,结果却是"11+22"
[root@ecs-b208 /]# aa=11
[root@ecs-b208 /]# bb=22
[root@ecs-b208 /]# echo $aa+$bb
11+22
[root@ecs-b208 /]#
如果需要进行数值运算,一般有三种方式:
declare
declare -i cc= a a + aa+ aa+bbexpr 或 let
命令 let cc= a a + aa+ aa+bb- 是用
$(( 算术表达式 ))
一般建议使用 let命令,简洁好记。
控制结构
3种 顺序 选择 循环 程序控制结构
if 语句
#! /bin/bash
if test -f "$1"
then
echo "$1 文件存在且为普通文件"
else
echo "$1 文件不存在或不是普通文件"
fi
上面的 test -f "$1"
作为测试条件 也可以写成[ -f "$1" ]
, [ ] 里面两端需要空格
注意,如果then 写在第一行,则 test -f "$1"
后面需要有分号
#! /bin/bash
if [ -f "$1" ] ; then
echo "$1 文件存在且为普通文件"
else
echo "$1 文件不存在或不是普通文件"
fi
多个分支:
#! /bin/bash
if [ 1 -eq $1 ] ; then
echo "输入的值等于1"
elif [ 2 -eq $1 ]; then
echo "输入的值等于2"
else
echo "$1 不等于1也不等于2"
fi
常见的条件表达式
主要在if语句中判断使用,这里常见的是整数、文件判断比较
- 整数比较符
比较符 | 描述 | 示例 |
---|---|---|
-eq, equal | 等于 | [ 1 -eq 1 ]为 true |
-ne, not equal | 不等于 | [ 1 -ne 1 ]为 false |
-gt, greater than | 大于 | [ 2 -gt 1 ]为 true |
-lt, lesser than | 小于 | [ 2 -lt 1 ]为 false |
-ge, greater or equal | 大于或等于 | [ 2 -ge 1 ]为 true |
-le, lesser or equal | 小于或等于 | [ 2 -le 1 ]为 false |
- 文件测试
测试符 | 描述 | 示例 |
---|---|---|
-e | 文件或目录存在为真 | [ -e path ] path 存在为 true |
-f | 文件存在为真 | [ -f file_path ] 文件存在为 true |
-d | 目录存在为真 | [ -d dir_path ] 目录存在为 true |
-r | 有读权限为真 | [ -r file_path ] file_path 有读权限为 true |
-w | 有写权限为真 | [ -w file_path ] file_path 有写权限为 true |
-x | 有执行权限为真 | [ -x file_path ] file_path 有执行权限为 true |
-s | 文件存在并且大小大于 0 为真 | [ -s file_path ] file_path 存在并且大小大于 0 为 true |
- 逻辑判断符
判断符 | 描述 | 示例 |
---|---|---|
&& | 逻辑与 | [[ 1 -eq 1 && 2 -eq 2 ]] 或 (( 1 == 1 && 2 == 2 )) |
|| | 逻辑或 | [[ 1 -eq 1 || 2 -eq 1 ]] 或 (( 1 == 1 || 2 == 2 )) |
- 字符串比较符
运算符 | 描述 | 示例 |
---|---|---|
== | 等于 | [ “a” == “a” ]为 true |
!= | 不等于 | [ “a” != “a” ]为 false |
> | 大于,判断字符串时根据 ASCII 码表顺序,不常用 | 在[]表达式中: [ 2 > 1 ]为 true 在[[]]表达式中: [[ 2 > 1 ]]为 true 在(())表达式中: (( 3 > 2 ))为 true |
< | 小于,判断字符串时根据 ASCII 码表顺序,不常用 | 在[]表达式中: [ 2 < 1 ]为 false 在[[]]表达式中: [[ 2 < 1 ]]为 false 在(())表达式中: (( 3 < 2 ))为 false |
>= | 大于等于 | 在(())表达式中: (( 3 >= 2 ))为 true |
<= | 小于等于 | 在(())表达式中: (( 3 <= 2 ))为 false |
-n | 字符串长度不等于 0 为真 | VAR1=1;VAR2="" [ -n “ V A R 1 " ] 为 t r u e [ − n " VAR1" ]为 true [ -n " VAR1"]为true[−n"VAR2” ]为 false |
-z | 字符串长度等于 0 为真 | VAR1=1;VAR2="" [ -z “ V A R 1 " ] 为 f a l s e [ − z " VAR1" ]为 false [ -z " VAR1"]为false[−z"VAR2” ]为 true |
str | 字符串存在为真 | VAR1=1;VAR2="" [ $VAR1 ]为 true [ $VAR2 ]为 false |
case 语句
#! /bin/bash
echo -n "请输入你的答案:"
read answer
case $answer in
"yes") echo "你的答案是yes"
echo "你将获得1元奖励" ;;
"no") echo "你的答案是no,无奖励" ;;
*) echo "未知的答案" ;;
esac
case 以 case xxx in
开头, 以esac
结尾
每一个分支 以;;
结束
while 语句
计算一个从1开始累加到用户输入的值为止,输出累加结果:
#! /bin/bash
echo -n "请输入一个正整数n:"
read n
let m=1
let sum=0
while (( m <= n )); do
(( sum +=m ))
(( m++ ))
done
echo "累加结果: $sum"
for 语句
常用,简洁明了,用for实现上面 while的需求
#! /bin/bash
echo -n "请输入一个正整数n:"
read n
let sum=0
for (( i=1; i<=n; i++ )); do
((sum +=i))
done
echo "累加结果: $sum"
for in 语句
对于固定的循环列表可以采用 for in语法格式
#! /bin/bash
for n in 1 2 3 4 5 ; do
echo "值为 $n"
done
当然也可以直接读用户输入的列表
[root@ecs-b208 /]# cat ex-test.sh
#! /bin/bash
for str
do
echo "你输入了 $str"
done
[root@ecs-b208 ~]# source ex-test.sh a b c d
你输入了 a
你输入了 b
你输入了 c
你输入了 d
[root@ecs-b208 ~]#
select in 语句
select in 是shell独特的一种循环,适合终端交换场景, 一般配合 case in 使用
[root@ecs-b208 ~]# cat qiuxing.sh
#! /bin/bash
echo "请输入你想了解的球星:"
select name in "梅西" "C罗" "内马尔" "姆巴佩" "哈兰德" "苏牙"
do
case $name in
"梅西") echo "阿根廷球星,获得6座金球奖"
break;;
"C罗") echo "葡萄牙球星,获得5座金球奖"
break;;
"内马尔") echo "巴西球星,带球过人风骚"
break;;
"姆巴佩") echo "用速度生吃对手"
break;;
"哈兰德") echo "铁柱中锋,推不倒,防不住"
break;;
"苏牙") echo "神仙球制造者,顶级前锋"
break;;
*) echo "对不起还没有该球星的资料,请重新输入" ;;
esac
done
运行结果如下:
[root@ecs-b208 ~]# source qiuxing.sh
请输入你想了解的球星:
1) 梅西
2) C罗
3) 内马尔
4) 姆巴佩
5) 哈兰德
6) 苏牙
#? 3
巴西球星,带球过人风骚
[root@ecs-b208 ~]#
break 和 continue 关键字
break 和 continue 关键字用于循环控制语句中,shell 中 break 和 continue 可以跳出多层循环。
break n n代表跳出循环的层数,不填写默认跳出整个循环
continue n 表示结束本次循环,直接运行next n循环,如果省略n 表示只控制当前循环
。
函数定义
function name() {
执行语句
[return value] # 可有可无
}
可以直接在shell命令行定义,例如:
[root@ecs-b208 ~]# function myprint() {
> echo "hello 这是一个函数"
> }
[root@ecs-b208 ~]# myprint
hello 这是一个函数
-
shell 中的函数定义 用关键字
function
来定义函数 -
shell 中的函数只要一个名字即可,
不用指明本函数可接受的参数
-
函数内部可以使用
$n 来接受, $1 表示第2个参数 $2 表示第2个参数
-
return 在函数中定义状态返回值,返回并终止函数,但返回的只能是 0-255 的数字,类似于 exit
综合使用案例
if和for组合使用
[root@ecs-b208 ~]# cat iffor.sh
#! /bin/bash
function checkParam() {
if [ $# -ge 1 ]; then
echo "一共输入了$#个参数,分别是:"
for ((i=1;i<=$#;i++)) ; do
echo "$i"
done
else
echo "$1 请在执行此函数时,输入几个参数"
fi
}
[root@ecs-b208 ~]# source iffor.sh
[root@ecs-b208 ~]# checkParam a b c
一共输入了3个参数,分别是:
1
2
3
检查主机是否存活
#!/bin/bash
if ping -c 1 192.168.1.1 >/dev/null; then
echo "OK."
else
echo "NO!"
fi