Shell是什么
Shell的分类
Bourne Shell:从1979起Unix就开始使用 Bourne Shell,Bourne Shell的主文件名为 sh。
C Shell: C Shell主要在BSD版的Unix系 统中使用,其语法和C语言相类似而得名
Shell 的两种主要语法类型有Bourne和C, 这两种语法彼此不兼容。
Bourne家族主要包括sh、ksh、Bash、psh、zsh;
C 家族主要包括:csh、tcsh
Bash: Bash与sh兼容,现在使用的Linux 就是使用Bash作为用户的基本Shell。
Linux支持的Shell
存放在文件里:/etc/shells
默认情况下有:
/bin/sh
/bin/bash
/sbin/nologin
/bin/tcsh
/bin/csh
脚本文件一般是 .sh 结尾。
执行:
bash test.sh #绝对路径或相对路径皆可
有一个操作:
如果从Windows里面拷贝一个脚本到Linux 虽然有的时候格式一样但是还是会报错,这便是因为两个系统中脚本的格式不同,比如Windows中的回车在脚本中用^M 表示,而 L i n u x 中为 表示,而Linux中为 表示,而Linux中为,(可以用cat -A [文件名] 来查询)所以需要转变,此时用到一个命令:dos2unix [文件名]
转换后,Linux就可以执行啦,通过没有这个命令可以使用yum安装
历史命令
history [选项] [历史命令保存文件]
历史命令默认会保存1000条,可以在环境 变量配置文件/etc/profile中进行修改
找到HISTSIZE=1000进行修改,随意修改到100000条都可以,修改之后重启使配置文件生效
历史命令的调用
命令与文件补全
在Bash中,在输入命令或文件时,按“Tab”键就会自动进行补全
命令别名
alias 别名=‘原命令’ 设定命令别名
alias 查询命令别名
命令执行时顺序:
让别名永久生效:
vi /root/.bashrc
删除别名
unalias 别名
Bash常用快捷键
快捷键 作用
ctrl+a 把光标移动到命令行开头。如果我们输入的命令过长,想要把光标移 动到命令行开头时使用。
ctrl+e 把光标移动到命令行结尾。
ctrl+c 强制终止当前的命令。
ctrl+l 清屏,相当于clear命令。
ctrl+u 删除或剪切光标之前的命令。我输入了一行很长的命令,不用使用退 格键一个一个字符的删除,使用这个快捷键会更加方便
ctrl+k 删除或剪切光标之后的内容。
ctrl+y 粘贴ctrl+U或ctrl+K剪切的内容。
ctrl+r 在历史命令中搜索,按下ctrl+R之后,就会出现搜索界面,只要输入 搜索内容,就会从历史命令中搜索。
ctrl+d 退出当前终端。
ctrl+z 暂停,并放入后台。这个快捷键牵扯工作管理的内容,我们在系统管 理章节详细介绍。
ctrl+s 暂停屏幕输出。
ctrl+q 恢复屏幕输出。
注意:ctrl+z 快捷键一定要谨慎使用,如果使用的多了,系统会占用大量存储空间来存放暂停的数据,用多了系统会变卡!!!
标准输入输出
设备 | 设备文件名 | 文件描述符 | 类型 |
---|---|---|---|
键盘 | /dev/stdin | 0 | 标准输入 |
显示器 | /dev/sdtout | 1 | 标准输出 |
显示器 | /dev/sdterr | 2 | 标准错误输出 |
输出重定向
类型 | 符号 | 作用 |
---|---|---|
标准输出重定向 | 命令 > 文件 | 以覆盖的方式,把命令的正确输出输出到指定的文件或设备当中。 |
标准输出重定向 | 命令 >> 文件 | 以追加的方式,把命令的正确输出输出到指定的文件或设备当中。 |
标准错误输出重定向 | 错误命令 2>文件 | 以覆盖的方式,把命令的错误输出输出到指定的文件或设备当中。 |
标准错误输出重定向 | 错误命令 2>>文件 | 以追加的方式,把命令的错误输出输出到指定的文件或设备当中。 |
在输入报错文件中 2和>>必选连着写 。
标准错误输出不常用
类型 | 符号 | 作用 |
---|---|---|
正确输出和错误输出同时保存 | 命令 > 文件 2>&1 | 以覆盖的方式,把正确输 出和错误输出都保存到同 一个文件当中。 |
正确输出和错误输出同时保存 | 命令 >> 文件 2>&1 | 以追加的方式,把正确输 出和错误输出都保存到同 一个文件当中。 |
正确输出和错误输出同时保存 | 命令 &>文件 | 以覆盖的方式,把正确输出和错误输出都保存到同一个文件当中。 |
正确输出和错误输出同时保存 | 命令 &>>文件 | 以追加的方式,把正确输出和错误输出都保 |
正确输出和错误输出同时保存 | 命令 >> 文件1 2>>文件2 | 把正确的输出追加到文件1中,把错误的输出追加到文件2中。 |
命令 >> 文件 2>&1
,命令 &>>文件
, 两种保存都一样,只不过是格式不同。
有一个用法:
命令 &>/dev/unll
不管命令是否正确,直接丢入这个文件夹,不保存任何数据,在写shell脚本时有用 。
输入重定
不通过键盘输入,通过文件输入,在实际中用的不多,用在给源码包打补丁。
wc [选项] [文件名]
用法:
命令 < 文件
: 把文件作为命令的输入。
命令 << 标识符
: 一直输入,直到输入标识停止输入把标识符之间内容作为命令的输入。
**管道符作用:**链接多个命令,把命令1的结果作为命令2的操作对象。
管道是一种通信机制,通常用于进程间的通信。它表现出来的形式将前面每一个进程的输出(stdout)直接作为下一个进程的输入(stdin)
命令1 | 命令2
注意:命令1的正确输出作为命令2的操作对象
grep : 主要用于过滤
grep [选项] 文件名/路径内容
ls / | grep “y”
#针对上面这个命令说明:
#以管道作为分界线,前面的命令有个输出,后面需要先输入(缺少查找范围),然后再过滤,最后再输出,通俗的讲就是管道前面的输出就是后面指令的输入。
为了便于理解,上述的指令变相实现可以如下:
ls / > xxx.txt #将ls /的结果保存到xxx.txt文件中
grep “y” xxx.txt #使用grep指令搜索xxx.txt中的包含y的行
xargs命令扩展
问题:为什么需要xargs命令?
答:之所以能用到这个命令,关键是由于很多命令不支持|管道来传递参数,而日常工作中有有这个必要,所以就有了 xargs 命令。
首先来看一个命令:
find /etc -name "*.conf" | ls -l #(错误)
find /etc -name "*.conf" | xargs ls -l #(正确
- xargs 可以将管道或标准输入(stdin)数据转换成命令行参数,也能够从文件的输出中读取数据。
- xargs 也可以将单行或多行文本输入转换为其他格式,例如多行变单行,单行变多行。
- xargs 默认的命令是 echo,这意味着通过管道传递给 xargs 的输入将会包含换行和空白,不过通过 xargs 的处理,换行和空白将被空格取代。
- xargs 是一个强有力的命令,它能够捕获一个命令的输出,然后传递给另外一个命令。
cat word.txt|xargs #多行输入单行输出
cat word.txt|xargs -n #多行输出
ls / | wc -l #统计“/”下的文档的个数
cat /etc/passwd | wc -l #统计有多少个用户信息
多命令执行符 | 格式 | 作用 |
---|---|---|
; | 命令1 ;命令2 | 多个命令顺序执行,命令之间没有任何逻辑联系,就算第一条报错,第二条也会执行 |
&& | 命令1 && 命令2 | 逻辑与当命令1正确执行,则命令2才会执行 当命令1执行不正确,则命令2不会执行 |
| | | 命令1 || 命令2 | 逻辑或当命令1 执行不正确,则命令2才会执行 当命令1正确执行,则命令2不会执行 |
磁盘文件复制:
dd if=输入文件 / of=输出文件 / bs=字节数/ count=个数
if=输入文件
指定源文件或源设备of=输出文件
指定目标文件或目标设备bs=字节数
指定一次输入/输出多少字节,即把这些字节看做 一个数据块count=个数
指定输入/输出多少个数据块这条命令可以把系统文件,磁盘都复制了,非常强大。
例子:
date ; dd if=/dev/zero of=/root/testfile bs=1k count=100000 ; date
通配符:
通配符 | 作用 |
---|---|
? | 匹配任意一个字符 |
* | 匹配0个或任意多个任意字符,也就是可以匹配任何内容 |
[] | 匹配中括号中任意一个字符。例如:[abc]代表一定匹配 一个字符,或者是a,或者是b,或者是c。 |
[-] | 匹配中括号中任意一个字符,-代表一个范围。例如:[a-z] 代表匹配一个小写字母。 |
[^] | 逻辑非,表示匹配不是中括号内的一个字符。例如:[ ^0- 9 ]代表匹配一个不是数字的字符。 |
特殊符号
符号 | 作用 |
---|---|
‘’ | 单引号。在单引号中所有的特殊符号,如“$”和“`”(反引号)都 没有特殊含义。 |
“” | 双引号。在双引号中特殊符号都没有特殊含义,但是“$”、“`” 和“\”是例外,拥有“调用变量的值”、“引用命令”和“转义符”的特殊含义。 |
`` | 反引号。反引号括起来的内容是系统命令,在Bash中会先执行它。 和 ( ) 作用一样,不过推荐使用 ()作用一样,不过推荐使用 ()作用一样,不过推荐使用(),因为反引号非常容易看错。 |
$() | 和反引号作用一样,用来引用系统命令。 |
# | 在Shell脚本中,#开头的行代表注释。 |
$ | 用于调用变量的值,如需要调用变量name的值时,需要用$name 的方式得到变量的值。 |
\ | 转义符,跟在\之后的特殊符号将失去特殊含义,变为普通字符。 如 将输出“ 将输出“ 将输出“”符号,而不当做是变量引用。 |
通配符匹配文件名,正则匹配字符串。这种区分是Linux特点,其他语言往往不区分通配符和正则。或者说通配符仅仅是正则中的一个符号而已。
基础正则表达式
元字符 | 作用 |
---|---|
- | 前一个字符匹配0次或任意多次。 |
. | 匹配除了换行符外任意一个字符。 |
^ | 匹配行首。例如:^hello会匹配以hello开头的行。 |
$ | 匹配行尾。例如:hello&会匹配以hello结尾的行。 |
[] | 匹配中括号中指定的任意一个字符,只匹配一个字符。 例如:[aoeiu] 匹配任意一个元音字母,[0-9] 匹配任意一位 数字, [a-z][0-9]匹配小写字和一位数字构成的两位字符。 |
[^] | 匹配除中括号的字符以外的任意一个字符。例如:[^0-9] 匹配 任意一位非数字字符,[^a-z] 表示任意一位非小写字母。 |
\ | 转义符。用于取消讲特殊符号的含义取消。 |
{n} | 表示其前面的字符恰好出现n次。例如:[0-9]{4} 匹配4位数 字,[1][3-8][0-9]{9} 匹配手机号码。 |
{n\ } | 表示其前面的字符出现不小于n次。例如: [0-9]{2,} 表示两 位及以上的数字。 |
{n,m} | 表示其前面的字符至少出现n次,最多出现m次。例如: [a- z]{6,8} 匹配6到8位的小写字母。 |
注意:斜杠 \ 是转移符。 使用"{" , “}” 需要使用转义符。
grep 过滤指令示例:
-i:忽略大小写
-c:只输出匹配行的数量
-l:只列出符合匹配的文件名,不列出具体的匹配行
-n:列出所有的匹配行,并显示行号
-h:查询多文件时不显示文件名
-v:显示不包含匹配文本的所有行
-w:匹配整词
-x:匹配整行
-r:递归搜索
“ *
”前一个字符匹配 0 次,或任意多次*
grep “a*” test_rule.txt
grep “aa*” test_rule.txt
grep “aaa*” test_rule.txt
grep “aaaaa*” test_rule.txt
“.
” 匹配除了换行符外任意一个字符
grep “s…d” test_rule.txt
“s…d”会匹配在s和d这两个字母之间一定有两个字符的单词
grep “s.*d” test_rule.txt
匹配在s和d字母之间有任意字符*
grep “.*” test_rule.txt
匹配所有内容。
“^”
匹配行首,“$”
匹配行尾
grep “^M” test_rule.txt
grep “n$” test_rule.txt
grep -n “^$” test_rule.txt
“[]
” 匹配中括号中指定的任意一个 字符,只匹配一个字符
grep “s[ao]id” test_rule.txt
grep “[0-9]” test_rule.txt
grep “^[a-z]” test_rule.txt
grep “^[ ^a-z ]” test_rule.txt
grep “^[ ^a-z A-Z ]” test_rule.txt
“\
” 转义符
grep “\.$” test_rule.txt
匹配使用“.”结尾的行
“{n}”表示其前面的字符恰好出现n次
grep “a\{3\}” test_rule.txt
匹配a字母连续出现三次的字符串
grep “[0-9]\{3\}” test_rule.txt
匹配包含连续的三个数字的字符串
“{n,}”表示其前面的字符出现不小于n次
grep “^\[0-9]\{3,\}[a-z]” test_rule.txt
匹配最少用连续三个数字开头的行
“{n,m}”匹配其前面的字符至少出现n次, 最多出现m次
grep “sa\{1,3\}i” test_rule.txt
匹配在字母s和字母i之间有最少一个a,最多三个a
cut [选项] 文件名
特点:
1.提取多列时,用“,”隔开就可以
cut -f 2 student.txt
cut -f 2,3 student.txt
2.有具体分割符时,也可以没有Tab键
cut -d “:” -f 1,3 /etc/passwd
: 以:为分隔符取1,3列
3.一般在使用cut命令的时候和管道符“|”连着使用
局限性:
cat不支持空格“ ”作为分隔符。因为机器识别的空格和输出的空格数可能不一致。(这里很玄学,你可以自己跑跑试试,确实是这样的)
应取而代之以制表符 tab 。
配合grep:
#得到passwd里的非root普通用户名
cat /etc/passwd | grep /bin/bash | grep -v root |cut -d ":" -f 1
printf ‘输出类型+输出格式’ 输出内容
输出类型:
输出格式:
\a: 输出警告声音
\b: 输出退格键,也就是Backspace键
\f: 清除屏幕
\n: 换行
\r: 回车,也就是Enter键
\t: 水平输出退格键,也就是Tab键 \v: 垂直输出退格键,也就是Tab键
每有一个%s代表每几个字符输出一次
%s %s %s\n 代表没三个字符输出一次并且换行
他在与cat命令结合使用的时候,需要用$()把cat命令扩起来,使用这种命令赋予变量的方式,才能正确输出文件内容,但是具体格式还得用%s\t 或者%s\n控制。
printf ‘%s’ $(cat student.txt) #不调整输出格式
printf ‘%s\t %s\t %s\t %s\t %s\t %s\t \n’ $(cat student.txt) #调整格式输出
printf 不接收管道符输出,也不能指定文件名(会被当成字符串)。
因为 awk 命令不支持 echo 和 cat 命令,所以 printf主要在 awk 命令编程中使用。
在awk命令的输出中支持print和printf命令。
printf
: printf是标准格式输出命令,并不会自动加入换行符,如果需要换行,需要手工
awk命令也叫awk编程,可以识别非制表符的空格,用来解决cut命令解决不了的提取列工作,他是把需要提取的原文件一行一行扫描,扫描每一行中所需要点列,然后把它记录下来,在全部扫描完之后全部打印出来。
awk ‘条件1{动作1} 条件2{动作2}…’ 文件名
条件(Pattern):
一般使用关系表达式作为条件
x > 10 判断变量 x是否大于10
x>=10 大于等于
x<=10 小于等于
动作(Action):
格式化输出流程控制语句。
可以是函数,可以是 print/printf
,可以是流程控制。
例子:
vi student.txt
ID Name PHP Linux MySQL Average
1 Liming 82 95 86 87.66
2 Sc 74 96 87 85.66
3 Gao 99 83 93 91.66#提取第2列和第6列。 awk ‘{printf $2 “\t” $6 “\n”}’ student.txt #提取 df -h命令显示之后的内容中第一列和第三列 df -h | awk '{print $1 “\t” $3}' #关系运算符 cat student.txt | grep -v Name | awk '$6 >= 87 {printf $2 “\n” }'
其中**$2代表第2列,$6代表第6列**,他可以识别非制表符的空格,单引号里面直接大括号代表没有条件,只要是输入有内容全部符合。
一些特殊用法:
BEGIN
BEGIN必须是大写,他是一个条件。
awk ‘BEGIN{printf “This is a transcript \n” } {printf $2 “\t” $6 “\n”}’ student.txt
他会在打印出2,6行之前先输出一句话 This is a transcript
它的作用是强制执行BEGIN后的命令,再去执行接下来的筛选操作。
你可以理解为一个初始化命令。通常BEGIN用来指定分隔符。
内置变量 FS
:FS是用来指定分隔符的
默认空格和换行符为分隔符。
例子:FS=“:”就是指定:为分隔符
cat /etc/passwd | grep “/bin/bash” |
awk 'BEGIN {FS=":"} {printf $1 “\t” $3 “\n”}'
Q:这是打印用户信息地一和第三列,为什么需要在{FS=“:”} 前加BEGIN呢?
A:因为如果你不加BEGIN你会发现除了第一行,其他都已经按格式打印出来了,但是只有第一行会照原样输出,因为awk默认是空格为分隔符,他在执行这条命令的时候,第一行数据已经被扫描了,所以来不及修改格式。
加了BEGIN,他会第一步强制先把默认分隔符修改了。
sed命令:
sed 是一种几乎包括在所有 UNIX 平台(包括 Linux)的轻量级流编辑器。sed主要是用来将数据进行选取、替换、删除、新增的命令。
它不仅可以修改文件内容,还可以修改命令结果,支持管道符操作,这就是与vim最大的区别
sed [选项] ‘[动作]’ 文件名
选项:
动作:
例子: sed ‘2p’ student.txt
查看文件的第二行会显示:
ID Name PHP Linux MySQL Average 1 Liming 82 95 86 87.66 1 Liming 82 95 86 87.66 2 Sc 74 96 87 85.66 3 Gao 99 83 93 91.66 发现多了一行,因为一般sed命令会把所有数据都输出到屏幕 ,只不过会先输出你想要的,这时候就需要-n配合。
sed -n ‘2p’ student.txt
输入 -n 后就没有多余的了sed ‘2,4d’ student.txt
删除第二行到第四行的数据,但不修改文件本身sed ‘2a hello’ student.txt
在第二行后追加 ‘hello’sed ‘2i hello \ world’ student.txt
在第二行前插入两行数据sed '2c No such person‘ student.txt
替换第二行数据位 ‘No such person’
特殊用法: 数据替换。
sed ‘s/旧字串/新字串/g’ 文件名
例子:字符串替换
sed ‘3s/74/99/g’ student.txt
#在第三行中,把74换成99
sed -i ‘3s/74/99/g’ student.txt
#sed操作的数据直接写入文件
sed -e ‘s/Liming//g ; s/Gao//g’ student.txt
#同时把“Liming”和“Gao”替换为空
sort [选项] 文件名
例子:
sort /etc/passwd #排序用户信息文件 sort -r /etc/passwd #反向排序 sort -t “:” -k 3,3 /etc/passwd #指定分隔符是“:”,用第三字段开头,第三字段结尾排序,就是只用第三字段排序,但是他不认识数字,会把数字当成字符串,认为3比11大 ,所以我需要加-n,进行数值排序 sort -n -t “:” -k 3,3 /etc/passwd
wc [选项] 文件名
测试选项 | 作用 |
---|---|
-b 文件 | 判断该文件是否存在,并且是否为 块设备文件(是块设备文件 为真) |
-c文件 | 判断该文件是否存在,并且是否为字符设备文件(是字符设备 文件为真) |
-d 文件 | 判断该文件是否存在,并且是否为目录文件(是目录为真) |
-e 文件 | 判断该文件是否存在(存在为真) |
-f 文件 | 判断该文件是否存在,并且是否为普通文件(是普通文件为真) |
-L 文件 | 判断该文件是否存在,并且是否为管道文件(是管道文件为真) |
-p 文件 | 判断该文件是否存在,并且是否为符号链接文件(是符号链接 文件为真) |
-s 文件 | 判断该文件是否存在,并且是否为非空(非空为真) |
-S 文件 | 判断该文件是否存在,并且是否为套接字文件(是套接字文件 为真) |
上面的表结合以下命令来判断:
两种判断格式
示例:
在判断之后,使用echo $?来观察输出语句是否为真
[ -d /root ] && echo “yes” || echo "no"
第一个判断命令如果正确执行,则打印“yes”,否则打印“no”
测试选项 | 作用 |
---|---|
-r 文件 | 判断该文件是否存在,并且是否该文件拥有读权限(有读 权限为真) |
-w文件 | 判断该文件是否存在,并且是否该文件拥有写权限(有写 权限为真) |
-x 文件 | 判断该文件是否存在,并且是否该文件拥有执行权限(有 执行权限为真) |
-u 文件 | 判断该文件是否存在,并且是否该文件拥有SUID权限(有 SUID权限为真) |
-g 文件 | 判断该文件是否存在,并且是否该文件拥有SGID权限(有 SGID权限为真) |
-k 文件 | 判断该文件是否存在,并且是否该文件拥有SBit权限(有 SBit权限为真) |
示例:
[ -w student.txt ] && echo “yes” || echo “no”
判断文件是拥有写权限的
不过系统不会区分,比如-w,只要(所有者,所属组,其他人)其中有一个有写权限,他就会返回yes,所以这个时候就需要我们自己写脚本 。
测试选项 | 作用 |
---|---|
文件1 -nt 文件2 | 判断文件1的修改时间是否比文件2的新(如果新则为真) |
文件1 -ot 文件2 | 判断文件1的修改时间是否比文件2的旧(如果旧则为真) |
文件1 -ef 文件2 | 判断文件1是否和文件2的Inode号一致,可以理解为两个文件是否为同一个文件。这个判断用于判断硬链接是很好的方法 |
例子:
ln /root/student.txt /tmp/stu.txt
先创建一个硬链接
[ /root/student.txt -ef /tmp/stu.txt ] && echo “yes” || echo “no” yes
然后用test测试
测试选项 | 作用 |
---|---|
整数1 -eq 整数 2 | 判断整数1是否和整数2相等(相等为真) |
整数1 -ne 整数 2 | 判断整数1是否和整数2不相等(不相等位置) |
整数1 -gt 整数2 | 判断整数1是否大于整数2(大于为真) |
整数1 -lt 整数2 | 判断整数1是否小于整数2(小于位置) |
整数1 -ge 整数2 | 判断整数1是否大于等于整数2(大于等于为真) |
整数1 -le 整数2 | 判断整数1是否小于等于整数2(小于等于为真) |
例子:
- [ 23 -ge 22 ] && echo “yes” || echo “no” yes
判断23是否大于等于22- [ 23 -le 22 ] && echo “yes” || echo “no” no
判断23是否小于等于22
测试选项 | 作用 |
---|---|
-z 字符串 | 判断字符串是否为空(为空返回真) |
-n 字符串 | 判断字符串是否为非空(非空返回真) |
字串1 ==字串2 | 判断字符串1是否和字符串2相等(相等返回真) |
字串1 != 字串2 | 判断字符串1是否和字符串2不相等(不相等返回真) |
例子:
1.name=sc
给name变量赋值
2.[ -z “$name” ] && echo “yes” || echo “no” no
判断name变量是否为空,因为不为空,所以返回no
aa=11
bb=22
先给变量aa和变量bb赋值
[ “$aa” == “$bb" ] && echo “yes” || echo "no"
然后判断两个变量的值是否相等,明显不相等 ,所以返回no
测试选项 | 作用 |
---|---|
判断1 -a 判断2 | 逻辑与,判断1和判断2都成立,最终的结果才为真 |
判断1 -o 判断2 | 逻辑或,判断1和判断2有一个成立,最终的结果就为 真 |
!判断 | 逻辑非,使原始的判断式取反 |
例子:
aa=11
[ -n “$aa” -a “$aa” -gt 23 ] && echo “yes” || echo "no"
判断变量aa是否有值,同时判断变量aa的是否大于23
因为变量aa的值不大于23,所以虽然第一个判断值为真, 返回的结果也是假
aa=24
[ -n “$aa” -a “$aa” -gt 23 ] && echo “yes” || echo “no” yes
两种形式,区别在 ;
if [ 条件判断式 ];then
程序
fi
##########
if [ 条件判断式 ]
then
程序
fi
单分支条件语句需要注意几个点
if语句使用fi结尾,和一般语言使用大括号结尾不同
[ 条件判断式 ]就是使用test命令判断,所以中括号和条件判断式之间必须有空格
then后面跟符合条件之后执行的程序,可以放在[]之后,用“;”分割。也可以换行写入,就不需要“;”了
if [ 条件判断式]
then
条件成立时,执行的程序
else
条件不成立时,执行的另一个程序
fi
##########
if [ 条件判断式1 ]
then
当条件判断式1成立时,执行程序1
elif [ 条件判断式2 ]
then
当条件判断式2成立时,执行程序2
#...省略更多条件...
else
当所有条件都不成立时,最后执行此程序
fi
case $变量名 in
"值1")
如果变量的值等于值1,则执行程序1
;;
"值2")
如果变量的值等于值2,则执行程序2
;;
#...省略其他分支...
*)
如果变量的值都不是以上的值,则执行此程序
;;
esac
示例:
#!/bin/bash #判断用户输入
#Author: yangyang (E-mail: [email protected])
read -p "Please choose yes/no: " -t 30 cho
case $cho in
"yes")
echo "Your choose is yes!"
;;
"no")
echo "Your choose is no!"
;;
*)
echo "Your choose is error!"
;;
esac
两种表示方法
for 变量 in 值1 值2 值3
do
程序
done
###############
for ((初始值;循环控制调节;变量变化)) #C 风格啦
do
程序
done
例子:
#打印时间
#!/bin/bash
for time in morning noon afternoon evening
do
echo “This time is $time!”
done
#批量解压缩软件包
#!/bin/bash
cd /lamp
ls *.tar.gz > ls.log #ls *.tar.gz 输出结果覆盖到ls.log文件
for i in $(cat ls.log)
do
tar -zxf $i $>/dev/null
done
rm -rf /lamp/ls.log
#批量添加新用户
read -p "Please input user name: " -t 30 name #输入用户名,等待时间30s
read -p "Please input the number of users: " -t 30 num #输入创建用户个数,等待时间30s
read -p "Please input the password of users: " -t 30 pass #输入用户密码,等待时间30s
if [ ! -z "$name" -a ! -z "$num" -a ! -z "$pass" ] #判断输入信息是否为空
then
y=$(echo $num | sed s/'^[0-9]*$'//g) #这里是判断输入的用户个数是否为数字,sed后也可以把^[0-9]*$换为's/[0-9]//g'
if [ -z "$y" ] #如果上一条语句输出不为空,就是输入的用户个数为数字,继续执行
then
for ((i=1;i<=$num;i++)) #开始循环
do
/usr/sbin/useradd "$name$i" &>/dev/null #建立用户
echo $pass | /usr/bin/passwd --stdin "$name$i" &>/dev/null #设置用户密码,与用户名相同
done
echo "Build seccees!"
fi
fi
如果输入的时候输错了需要按,ctrl+退格键
while 循环
while [ 条件判断式 ]
do
程序
done
#从1加到100
i=1
s=0
while [ $i -le 100 ] #如果变量i的值小于等于100,则执行循环
do
s=$(( $s+$i ))
i=$(( $i+1 ))
done
echo "The sum is: $s"
until 循环,和while循环相反,until循环时只要条件判断式不成立则进行循环,并执行循环程序。一旦循环条件成立,则终止循环。
until [ 条件判断式 ]
do
程序
done
#从1加到100
i=1
s=0
until [ $i -gt 100 ] #循环直到变量i的值大于100,就停止循环
do
s=$(( $s+$i ))
i=$(( $i+1 ))
done
echo "The sum is: $s"