目录Linux 快速学习总结 ( ͡° ͜ʖ ͡° ) 本文档采用 Centos Linux 8.x 学习测试
- 一、Linux 概述
- 前世今生
- 常用的几个版本
- 二、基本使用
- 命令的基本格式
- 简单命令使用
- 二进制包RPM
- 三、Shell 编程基础
- 通配符
- 引号
- 输入输出重定向
- 文件描述符
- 命令连接操作符
- 小括号和大括号
- 其他操作符
- 四、Shell编程
- 变量
- 用户自定义变量
- 数组变量
- 系统预定义变量
- 环境变量
- 数值运算
- 控制结构
- if 语句
- 常见的条件表达式
- case 语句
- while 语句
- for 语句
- for in 语句
- select in 语句
- break 和 continue 关键字
- 函数定义
- 综合使用案例
__ __ _______
/ | / | /
$$ | $$/ _______ __ __ __ __ $$$$$$$ | ______
$$ | / |/ / | / |/ / | $$ | $$ | /
$$ | $$ |$$$$$$$ |$$ | $$ |$$ /$$/ $$ | $$ |/$$$$$$ |
$$ | $$ |$$ | $$ |$$ | $$ | $$ $$< $$ | $$ |$$ | $$ |
$$ |_____ $$ |$$ | $$ |$$ __$$ | /$$$$ $$ |__$$ |$$ __$$ |
$$ |$$ |$$ | $$ |$$ $$/ /$$/ $$ | $$ $$/ $$ $$/
$$$$$$$$/ $$/ $$/ $$/ $$$$$$/ $$/ $$/ $$$$$$$/ $$$$$$/
一、Linux 概述
前世今生
Linux 是一种操作系统,它 = 内核 + 其他基础软件
Linux 内核1991年10月,由芬兰大学生 Linus Torvalds 带头开发的操作系统。
1992年Linux 内核与GNU软件(作为其他基础软件)结合,完全自由的操作系统 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 和 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 <文件描述符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脚本文件中定义, 编写格式 “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:数值运算: : :------: 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+bb
- expr 或 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 |
#! /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



