1)Shell是什么
2)Shell的分类
3)Linux支持的Shell
补充:Linux最常用的sh是bash。
1)echo输出命令
$ echo [选项] [输出内容]
选项:
$ echo -e "ab\bc"
# \b删除左侧字符
$ echo -e "a\tb\tc\nd\te\tf"
# \t制表符 \n换行符
$ echo -e "\x61\t\x62\t\x63\n\x64\t\x64\t\x66"
# \x按照十六进制ASCII码也同样可以输出(与上一个例子输出同样的结果)
$ echo -e "\e[1;31m abcd \e[0m"
# 输出颜色 \e[1;表示开始颜色输出 \e[0m表示结束颜色输出
# 30m=黑色,31m=红色,32m=绿色,33m=黄色
# 34m=蓝色,35m=洋红,36m=青色,37m=白色
补充:echo 后面双引号里面不能打印特殊符号,单引号里面可以。
2)第一个脚本
$ vim hello.sh
#!/bin/bash
# The first program
# Author: ACGkaka(Email:[email protected])
echo "Linux learning every day, happy every day."
3)脚本执行
1)历史命令
$ history [选项] [历史命令保存文件]
选项:
-c 清空历史命令
-w 把缓存中的历史命令写入历史命令保存文件~/.bash_history
历史命令默认会保存1000条,可以在环境变量配置文件/etc/profile中进行修改
历史命令的调用
2)命令与文件补全
Tab
键就会自动进行补全。1)命令别名
$ alias 别名='原命令'
# 设定命令别名
$ alias
# 查询命令别名
命令执行时顺序
$ vim /root/.bashrc
# 让别名永久生效,写入文件
$ unalias 别名
# 临时删除别名
2)Bash常用快捷键
1)标准输入输出
设备 | 设备文件名 | 文件描述符 | 类型 |
---|---|---|---|
键盘 | /dev/stdin | 0 | 标准输入 |
显示器 | /dev/stdout | 1 | 标准输出 |
显示器 | /dev/stderr | 2 | 标准错误输出 |
2)输出重定向
3)输入重定向
$ wc [选项] 文件名
选项:
-c 统计字节数
-w 统计单词数
-l 统计行数
命令<文件 把文件作为命令的输入
命令<< 标识符
……
标识符 把标识符之间内容作为命令的输入
1)多命令顺序执行
多命令执行符 | 格式 | 作用 |
---|---|---|
; | 命令1 ; 命令2 | 多个命令顺序执行,命令之间没有任何逻辑联系 |
&& | 命令1 && 命令2 | 逻辑与 当命令1正确执行,则命令2才会执行 当命令1执行不正确,则命令2不会执行 |
|| | 命令1 || 命令2 | 逻辑非 当命令1执行不正确,则命令2才会执行 当命令1正确执行,则命令2不会执行 |
示例:
$ ls ; date ; cd /usr ; pwd
# 判断命令是否执行成功
$ ls anaconda-ks.cfg && echo yes
# 判断命令是否执行失败
$ ls /root/test || echo no
# 判断命令执行成功还是失败
$ 命令 && echo yes || echo no
读取、转换并输出命令 dd
$ dd if=输入文件 of=输出文件 bs=字节数 count=个数
选项:
示例:
$ date ; dd if=/dev/zero of=/root/testfile bs=1k count=100000 ; date
# 实现文件内容拷贝
2)管道符
$ 命令1 | 命令2
# 命令1的正确输出,作为命令2的操作对象
示例:
$ ll -a /etc/ | more
$ netstat -an | grep "ESTABLISHED"
管道符最常用命令 grep
$ 命令 | grep [选项] 搜索内容
选项:
1)通配符
通配符 | 作用 |
---|---|
? | 匹配一个任意字符 |
* | 匹配0个或任意多个任意字符,也就是可以匹配任何内容 |
[] | 匹配中括号中的任意一个字符。例如:[abc]代表匹配a、b、c中的任意一个字符。 |
[-] | 匹配中括号中的任意一个字符,-代表一个范围。例如:[a-z]代表匹配任意一个小写字母。 |
[^] | 逻辑非,代表匹配不是中括号中的一个字符。例如:[^0-9]代表匹配一个不是数字的字符。 |
示例:
$ cd /tmp/
$ rm -rf *
$ touch abc
$ touch 012
$ touch 0abc
$ ls ?abc
# 匹配 0abc
$ ls [0-9]*
# 匹配 012
$ ls [^0-9]*
# 匹配 abc
补充:通配符主要用于匹配文件名
2)Bash中的其他特殊符号
符号 | 作用 |
---|---|
’ | 单引号。在单引号中的所有特殊符号,如$和`(反引号)都没有特殊含义。 |
" | 双引号。在双引号中特殊符号都没有特殊含义,但是"$“、”`“、”\" 是例外,拥有"调用变量的值"、“引用命令”、"转义符"的特殊含义。 |
` | 反引号。反引号括起来的内容是系统命令,在Bash中会先执行它。和 ( ) 作用一样,不过推荐使用 ()作用一样,不过推荐使用 ()作用一样,不过推荐使用(),因为反引号非常容易看错。 |
$() | 和反引号作用一样,用来引用系统命令。 |
# | 在Shell脚本中,#开头的行代表注释。 |
$ | 用于调用变量的值,如需要调用变量name的值时,需要用$name的方式得到变量的值。 |
\ | 转义符,跟在\之后的特殊符号将失去特殊含义,变为普通字符。如\ 将输出为 将输出为 将输出为符号,而不当作时变量引用。 |
反引号与$()示例:
$ echo `date`
$ echo $(date)
# 两条命令执行结果相同
单引号与双引号示例:
$ name=sc
$ echo '$name'
# 输出$name
$ echo "$name"
# 输出sc
$ echo '$(date)'
# 输出$(date)
$ echo "$(date)"
# 输出Sat Dec 11 04:07:23 PST 2021
1)什么是变量
2)变量设置规则
3)变量分类
4)本地变量
变量定义
$ name="ACGkaka"
变量叠加
$ aa=123
# aa为123
$ aa="$aa"456
# aa为123456
$ aa=${aa}789
# aa为123456789
变量调用
$ echo $name
变量查看
$ set | grep name=
变量删除
$ unset name
1)环境变量是什么
2)设置环境变量
$ export 变量名=变量值
# 声明变量
$ env
# 查询变量
$ unset 变量名
# 删除变量
3)系统常见环境变量
PATH:系统查找命令的路径
$ echo $PATH
# /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:
$ PATH="$PATH":/root/sh
# PATH变量叠加
PS1:定义系统提示符的变量
\d:显示日期,格式为“星期 月 日”
\h:显示简写主机名。如默认主机名“localhost”
\t:显示24小时制时间,格式为“HH:MM:SS”
\T:显示12小时制时间,格式为“HH:MM:SS”
\A:显示24小时制时间,格式为“HH:MM”
@:显示12小时制时间,格式为“HH:MM AM/PM”
\u:显示当前用户名
\w:显示当前所在目录的完整名称
\W:显示当前所在目录的最后一个目录
\#:执行的第几个命令
\KaTeX parse error: Expected 'EOF', got '#' at position 22: …果是root用户会显示提示符为#̲,如果是普通用户会显示提示符为
示例:
[root@localhost ~]$ PS1='[\u@\t \w]\$'
# 系统默认提示符为PS1='[\u@\h \W]\$'
[root@04:50:08 /usr/local/src]$ PS1='[\u@\@ \h \# \W]\$'
[root@04:53 AM localhost 31 rsc]$
1)位置参数变量
位置参数变量 | 作用 |
---|---|
$n | n为数字,$0代表命令本身,$1- 9 代表第一到第九个参数,十以上的参数需要用大括号包含,如 9代表第一到第九个参数,十以上的参数需要用大括号包含,如 9代表第一到第九个参数,十以上的参数需要用大括号包含,如{10} |
$* | 这个变量代表命令行中所有的参数,$*把所有的参数看成一个整体 |
$@ | 这个变量也代表命令行中所有的参数,不过$@把每个参数区分对待 |
$# | 这个变量代表命令行中所有参数的个数 |
示例1:
#!/bin/bash
num1=$1
num2=$2
sum=$(( $num1 + $num2 ))
# 变量sum的和是num1加num2
echo $sum
# 打印变量sum的值
示例2:
#!/bin/bash
echo "A total of $# parameters"
# 使用$#代表所有参数的个数
echo "The parameter is: $*"
# 使用$*代表所有的参数
echo "The parameter is: $@"
# 使用$@也代表所有参数
示例3:$*与$@的区别
#!/bin/bash
for i in $*
# $*中的所有参数看成是一个整体,所以这个for循环只会循环一次
do
echo "The parameter is: $i"
done
x=1
for y in $@
# $@中的每个参数都看成是独立的,所以"$@"是一个数组,有几个参数,就会循环几次
do
echo "The parameter is: $y"
x=$(( $x + 1 ))
done
1)预定义变量
预定义变量 | 作用 |
---|---|
$? | 最后一次执行的命令的返回状态。 值为0,证明上一个命令正确执行;值为非0,则证明上一个命令执行不正确了。(具体是哪个数,根据脚本对错误的定义而定) |
$$ | 当前进程的进程号(PID) |
$! | 后台运行的最后一个进程的进程号(PID) |
示例:
$ vim variable.sh
#!/bin/bash
# Author:ACGkaka(E-mail:[email protected])
echo "The current process is $$"
# 输出当前进程的PID。
# 这个PID就是variable.sh这个脚本执行时,生成的进程的PID
find /root -name hello.sh &
# 使用find命令在root目录下查找hello.sh文件
# 符号&的意思是把命令放入后台执行
echo "The last one Daemon process is $"
补充:逻辑与&&、逻辑或|| 是怎么判断命令有没有正确执行的,就是通过$?s
2)接受键盘输入
$ read [选项] 变量名
选项:
示例:
#!/bin/bash
# Author:ACGkaka(E-mail:[email protected])
read -t 30 -p "Please input your name: " name
# 提示“请输入姓名”,并等待30秒,把用户的输入保存入变量name中
echo "Name is $name"
read -s -t 30 -p "Please enter your age: " age
# 年龄时隐私,所以我们用“-s”选项隐藏输入
echo -e "\n"
# echo -e 输出转移字符 -n 输出不换行
echo "Age is $age"
read -n 1 -t 30 -p "Please select your gender[M|F]: " gender
# 使用“-n 1” 选项只接收一个输入字符就会执行(都不用输入回车)
echo -e "\n"
echo "Gender is $gender"
注意:在Linux当中,变量类型默认全部是字符串类型。
1)declare 声明变量类型
$ declare [+/-][选项] 变量名
选项:
2)数值运算
方法1:
$ aa=11
$ bb=22
# 给变量aa和bb赋值
$ declare -i cc=$aa+$bb
# cc=33
方法2:expr或let数值运算工具
$ aa=11
$ bb=22
# 给变量aa和变量bb赋值
$ dd=$(expr $aa + $bb)
# dd=33。注意:+两边必须有空格
方法3:$((运算式)) 或 $[运算式]
#!/bin/bash
$ aa=11
$ bb=22
$ ff=$(( $aa+$bb ))
$ gg=$[ $aa+$bb ]
运算式整理:
$(命令)
相当于`命令`$((运算式))
相当于$[运算式]${变量名}
相当于"$变量名"(包括双引号)[条件判断]
相当于“test 条件判断”3)运算符
示例:
$ aa=$(( (11+3)*3/2 ))
# 小学生数学,优先计算括号内的
$ bb=$(( 14%3 ))
# 14对3取余,结果为2
$ cc=$(( 1 && 0 ))
# 逻辑与运算,两边都为1才为1,否则为0
示例:测试x=${y-新值}
$ unset y
# 删除变量y
$ x=${y-new}
$ echo $x
# 因为变量y不存在,所以x=new
$ y=""
# 给变量y赋值为空
$ x=${y-new}
$ echo $x
# x为空
$ y=old
# 给变量y赋值
$ x=${y-new}
$ echo $x
# x=old
1)source命令
$ source 配置文件
# 或 $ .配置文件
补充:source 和. 可以让配置文件立即生效 而不需要重启。
2)环境变量配置文件简介
补充:/etc/下面的配置文件是对全部用户生效,~/下面的配置文件是对相应的用户生效。
配置文件:
配置文件生效顺序:
/etc/profile的作用:
~/.bash_profile的作用:
~/.bashrc的作用:
/etc/bashrc的作用:
1)注销时生效的环境变量配置文件
2)其他配置文件
3)Shell登录信息
本地终端欢迎信息:/etc/issue
远程终端欢迎信息:/etc/issue.net
登录后欢迎信息:/etc/motd
不管是本地登录,还是远程登录,都可以显示此欢迎信息。
1)正则表达式与通配符
2)基础正则表达式
“*”:前一个字符匹配0此,或任意多次。
$ grep "a*" test_rule.txt
# 匹配所有内容,包括空白行
$ grep "aa*" test_rule.txt
# 匹配至少包含有一个a的行
$ grep "aaa*" test_rule.txt
# 匹配最少包含2个连续a的字符串
$ grep "aaaaa*" test_rule.txt
# 匹配最少包含4个连续a的行字符串
“.”:匹配除了换行符外的任意一个字符。
$ 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
# 匹配以大写“M”开头的行
$ grep "n$" test_rule.txt
# 匹配以小写“n“结尾的行
$ grep -n "^$" test_rule.txt
# 匹配空白行
“[]”匹配中括号中指定的任意一个字符,只匹配一个字符。
$ grep "s[ao]id" test_rule.txt
# 匹配said和soid
$ grep "[0-9]" test_rule.txt
# 匹配任意一个数字
$ grep "^[a-z]" test_rule.txt
# 匹配以小写字母开头的行
“^”取反,匹配除中括号的字符以外的任意一个字符。
$ grep "^[^a-z]" test_rule.txt
# 匹配不是小写字母开头的行
$ grep "^[^a-zA-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
# 匹配sai、saai、saaai字符串所在的行
$ cut [选项] 文件名
选项:
示例:
$ vi student.txt
ID Name gender Mark
1 Liming M 86
2 Sc M 90
3 Gao M 83
# 创建测试用例
$ cut -f 2 student.txt
$ cut -f 2,3 student.txt
$ cut -d ":" -f 1,3 /etc/passwd
cut命令的局限:
如果是不是用固定的制表符、空格、固定字符串进行分割,无法正确拆分列,这时候需要使用awk。
$ df -h | cut -d " " -f 1,3
$ printf '输出类型输出格式' 输出内容
输出类型:
输出格式:
$ printf %s 1 2 3 4 5 6
# 输出123456
$ printf %s %s %s 1 2 3 4 5 6
# 输出%s%s123456
$ printf '%s %s %s' 1 2 3 4 5 6
# 输出1 2 34 5 6
$ printf '%s %s %s\n' 1 2 3 4 5 6
# 输出如下:
# 1 2 3
# 4 5 6
使用printf输出文本内容:
$ vim 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
$ printf '%s' $(cat student.txt)
# 不调整输出格式
$ printf '%s\t%s\t%s\t%s\t%s\t%s\t\n' $(cat student.txt)
# 调整格式输出
在awk命令的输出中支持print和printf命令:
$ awk '条件1{动作1} 条件2{动作2}...' 文件名
条件(Pattern):
动作(Action):
示例:
$ vim 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
$ awk '{printf $2"\t"$6"\n"}' student.txt
Name Average
Liming 87.66
Sc 85.66
Gao 91.66
$ df -h | awk '{print $1"\t"$3}'
BEGIN
$ awk 'BEGIN{printf "This is a transcript \n"} {printf $2"\t"$6"\n"}' student.txt
This is a transcript
Name Average
Liming 87.66
Sc 85.66
Gao 91.66
END
$ awk 'END{printf "The End. \n"} {printf $2"\t"$6"\n"}' student.txt
Name Average
Liming 87.66
Sc 85.66
Gao 91.66
The End.
FS内置变量
$ cat /etc/passwd | grep "/bin/bash" | \
awk 'BEGIN {FS=":"} {printf $1"\t"$3"\n"}'
root 0
zhj 1000
test 1001
补充:FS 作用是指定分隔符。
注意:awk命令默认先读取第一行,在执行命令,加了BEGIN之后就会限制性BEGIN中的命令,再读取内容,所以FS要加载BEGIN中,不然会少分析第一行。
关系运算符
$ cat student.txt | grep -v Name | \
awk '$6 >= 87 {printf $2"\n"}'
Liming
Gao
$ sed [选项] '[动作]' 文件名
选项:
动作:
学生成绩表
$ vim 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
行数据操作
$ sed '2p' student.txt
# 查看文件的第二行(打印第二行之后还会打印一遍全文)
$ sed -n '2p' student.txt
# 只查看文件的第二行
$ sed '2,4d' student.txt
# 删除第二行开始的四行数据,但不修改文件本身
$ sed '2a hello' student.txt
# 在第二行后追加一行 hello
$ sed '2i hello\
world' student.txt
# 在第二行前插入两行 hello\n world
$ sed '2c No such person'
# 将第二换内容替换
字符串替换
$ sed '行号s/旧字串/新字串/g' 文件名
$ sed '3s/74/99/g' student.txt
# 在第三行中,把74替换为99
$ sed -i '3s/74/99/g' student.txt
# 在第三行中,把74替换为99,并写入文件
$ sed -e 's/Liming//g; s/Gao//g' student.txt
# 同时把“Liming”和“Gao”替换为空
中括号[]替换
echo '[test]' |sed 's/[][]//g'
补充:sed 命令中单引号和双引号的用法区别:https://blog.csdn.net/genghongsheng/article/details/120432010
1)排序命令sort
$ sort [选项] 文件名
选项:
示例:
$ sort /etc/passwd
# 排序用户信息文件
$ sort -r /etc/passwd
# 反向排序
$ sort -t ":" -k 3,3 /etc/passwd
# 指定分隔符是“:”,用第三字段开头,第三字段结尾排序,就是只用第三字段排序
$ sort -n -t ":" -k 3,3 /etc/passwd
# 同上,增加了会将第三字段按照数值排序
2)统计命令wc
$ wc [选项] 文件名
选项:
查看条件判断结果的两种方式:
[ -e test.txt ] && echo “yes” || echo “no”
成功yes 失败no
[ -e test.txt ]
echo $?
成功0 失败1
1)按照文件类型进行判断
两种判断格式
$ test -e /root/install.log
$ [ -e /root/install.log ]
# 注意:[]内测两边必须要有空格
示例:
$ [ -d /root ] && echo "yes" || echo "no"
# 第一个判断命令如果正确执行,则打印“yes”,否则打印“no”
2)按照文件权限进行判断
示例:
$ [ -w student.txt ] && echo "yes" || echo "no"
# 判断文件是否拥有写权限
3)两个文件之间进行比较
测试选项 | 作用 |
---|---|
文件1 -nt 文件2 | 判断文件1的修改时间是否比文件2的新(如果新则为真) |
文件1 -ot 文件2 | 判断文件1的修改时间是否比文件2的旧(如果旧则为真) |
文件1 -ef 文件2 | 判断文件1是否和文件2的inode一致,可以理解为两个文件是否为同一个文件。这个判断是个用于判断硬链接的好方法。 |
示例:
$ ln /root/student.txt /tmp/stu.txt
# 创建个硬链接
$ [ /rooot/student.txt -ef /tmp/stu.txt ] && echo "yes" || echo "no"
# 用test测试下,果然很有用
4)两个整数之间比较
示例:
$ [ 23 -ge 22 ] && echo "yes" || echo "no"
# 判断23是否大于等于22,输出yes
$ [ 23 -le 22 ] && echo "yes" || echo "no"
# 判断23是否小于等于22,输出no
5)字符串的判断
示例:
$ name=sc
# 给name变量赋值
$ [ -z $name ] && echo "yes" || echo "no"
# 判断name变量是否为空或不存在,输出no
$ aa=11
$ bb=22
# 给变量aa和变量bb赋值
$ [ $aa==$bb ] && echo "yes" || echo "no"
# 判断两个变量的值是否相等,输出no
6)多重条件判断
示例:
$ aa=11
$ [ -n $aa -a $aa -gt 23 ] && echo "yes" || echo "no"
# 判断aa是否有值,同时判断aa的值是否大于23,输出no
1)单分支if条件语句
写法一:
if [ 条件判断式 ];then
程序
fi
写法二:(常用)
if [ 条件判断式 ]
then
程序
fi
单分支条件语句需要注意几个点
示例:
#!/bin/bash
# 统计根分区使用率
# Author: ACGkaka(E-mail: [email protected])
$ rate=$(df -h | grep "/dev/sda3" | awk '{print $5}' | cut -d "%" -f1)
# 把根分区使用率作为变量值赋予变量rate
if [ $rate -ge 80 ]
then
echo "Warning! /dev/sda3 is full!!
fi
2)双分支if条件语句
if [ 条件判断式 ]
then
条件成立时,执行的程序
else
条件不成立时,执行的另一个程序
fi
示例1:
#!/bin/bash
# 备份MySQL数据库
# Author: ACGkaka(E-mail: [email protected])
ntpdate asia.pool.ntp.org &>/dev/null
# 同步系统时间(需联网)
date=$(date +%y%m%d)
# 把当前系统时间按照“年月日”格式赋予变量date
size=$(du -sh /var/lib/mysql)
# 统计MySQL数据库的大小,并把大小赋予size变量
if [ -d /tmp/dbbak ]
then
echo "Date: $date" > /tmp/dbback/dbinfo.txt
echo "Data size: $size" >> /tmp/dbbak/dbinfo.txt
cd /tmp/dbbak
tar -zcf mysql-lib-$date.tar.gz /var/lib/mysql dbinfo.txt &>/dev/null
rm -rf /tmp/dbbak/dbinfo.txt
else
mkdir /tmp/dbbak
echo "Date: $date" > /tmp/dbbak/dbinfo.txt
echo "Date size: $size" >> /tmp/dbbak/dbinfo.txt
cd /tmp/dbbak
tar -zcf mysql-lib-$date.tar.gz /var/lib/mysql dbinfo.txt &>/dev/null
rm -rf /tmp/dbbak/dbinfo.txt
示例2:
#!/bin/bash
# 判断apache是否启动
# Author: ACGkaka(E-mail: [email protected])
port=$(nmap -sT 192.168.1.156 | grep tcp | grep http | awk '{print $2}')
# 使用nmap命令扫描服务器,并截取apache服务的状态,赋予变量port
if [ $port == open ]
then
echo "$(date) httpd is ok." >> /tmp/autostart-acc.log
else
/etc/rc.d/init.d/httpd start &>/dev/null echo "$(date) restart httpd..." >> /tmp/autostar-err.log
fi
补充:Linux 判断字符串是否相等用==
3)多分支if条件语句
if [ 条件判断式1 ]
then
当条件判断式1成立时,执行的程序
elseif [ 条件判断式2 ]
then
当条件判断式2成立时,执行的程序
……
else
当所有条件都不成立时,执行的程序
fi
示例:
#!/bin/bash
# 判断用户输入的是什么文件
# Author: ACGkaka(E-mail: [email protected])
read -p "Please input a filename: " file
# 接收键盘输入,并赋予变量file
if [ -z $file ]
# 判断file变量是否为空
then
echo "Error, file name cannot be empty"
exit 1
# 返回错误码1
elif [ ! -e $file ]
# 判断file的值是否存在
then
echo "Your input is not a file."
exit 2
# 返回错误码2
elif [ ! -f $file ]
# 判断file的值是否为普通文件
then
echo "$file is a regulare file."
elif [ -d $file ]
then
echo "$file is a directory."
else
echo "$file is an unkown file."
fi
多分支case语句
case $变量名 in
"值1")
如果变量的值等于值1,执行的程序
;;
"值2")
如果变量的值等于值2,执行的程序
;;
……
*)
如果变量的值都不是以上的值,则执行此程序
;;
esac
示例:
#!/bin/bash
# 判断用户输入
# Author: ACGkaka(E-mail: [email protected])
read -p "Please choose yes/no" -t 30 cho
# 读取用户输入,赋予变量cho
case $cho in
"yes")
echo "Your choose is yes."
;;
"no")
echo "Your choose is no."
;;
*)
echo "Your choose is invalid."
;;
esac
语法一:
for 变量 in 值1 值2 值3...
do
程序
done
示例1:
#!/bin/bash
# 打印时间
# Author: ACGkaka(E-mail: [email protected])
for time in morning noon afternoon evening
do
echo "This time is $time."
done
示例2:
#!/bin/bash
# 批量解压缩脚本
# Author: ACGkaka(E-mail: [email protected])
cd /lamp
ls *.tar.gz>ls.log
for i in $(cat ls.log)
do
tar -zxf $i &>/dev/null
done
rm -rf /lamp/ls.log
语法二:
for (( 初始值;循环控制条件;变量变化 ))
do
程序
done
示例1:
#!/bin/bash
# 从1加到100
# Author: ACGkaka(E-mail: [email protected])
s=0
for (( i=1;i<=100;i=i+1 ))
do
s=$(( $s+$i ))
done
echo "The sum of 1+2+...+100 is $s"
示例2:
#!/bin/bash
# 批量添加指定数量的用户
# Author: ACGkaka(E-mail: [email protected])
read -p "Please input user name: " -t 30 name
read -p "Please input the number of users: " -t 30 num
read -p "Please input the password of users: " -t 30 pass
if [ ! -z $name -a ! -z $num -a ! -z $pass ]
then
y=$(echo $num | sed 's/[0-9]*//g')
# 判断数量是否为数字
if [ -z $y ]
then
for (( i=1;i<=$num;i=i+1 ))
do
/usr/sbin/useradd $name$i &>/dev/null
echo $pass | /usr/bin/passwd --stdin $name$i &>/dev/null
done
1)while循环
while [ 条件判断式 ]
do
程序
done
示例:
#!/bin/bash
# 从1加到100
# Author: ACGkaka(E-mail:[email protected])
i=1
s=0
while [ $i -le 100 ]
# 如果变量i的值小于等于100,则循环执行
do
s=$(( $s+$i ))
i=$(( $i+1 ))
done
echo "The sum is: $s"
2)until循环
until [ 条件判断式 ]
do
程序
done
示例:
#!/bin/bash
# 从1加到100
# Author: ACGkaka(E-mail:[email protected])
i=1
s=0
until [ $i -gt 100 ]
# 循环直到变量i的值大于100,就停止循环
do
s=$(( $s+$i ))
i=$(( $i+1 ))
done
echo "The sum is: $s"
整理完毕,完结撒花~