shell 是什么
shell是一个命令处理器(command processor)——是一个读入并解释你输入的命令的程序。除了是一个命令中断器以外,shell还是一个程序设计语言。你可以编写shell可以解释的程序(被称为源程序),这些源程序可以包含shell程序设计命令等等。shell除了解释命令以外,还有其他工作,它也可以配置和编程。shell拥有自己的语言允许用户编写程序并以一种复杂方式运行。shell编程语言具有许多常用的编程语言的特征,例如:循环和控制结构等。用户可以生成像其他应用程序一样复杂的shell程序。
查看shell版本
bash是shell的一种,是大多数Linux发行版默认的shell,除bash shell外还有dash shell、rbash shell等其它类型的shell。
命令:cat /etc/shells
显示如下:
添加bash
命令:usermod -s /bin/bash python
注:bash shell是通行版本,且ubuntu默认bash shell
shell使用方法
手工调用:
命令:echo 命令
示例:echo ‘itcast’
脚本调用:
步骤:vim itcast.sh -> 编辑脚本(echo ‘itcast’) ->cat itcast.sh(查看脚本) -> /bin/bash itcast.sh(执行脚本)
注:脚本的作用为罗列手工执行方式
脚本内编辑内容:
注释
单行注释:#
多行注释::<<!..!
注:符号**!可替换为除#**以外任意符号,同时前后需保持一致
脚本执行方式
格式一:
bash 路径/文件名 或 /bin/bash 路径/文件名 (强烈推荐使用)
格式二:
路径/文件名 或 ./文件名 (当前路径下执行脚本)(需先修改文件权限 chmod)
格式三:
source 文件名 或 . 文件名 (注意“.“点号)
脚本开发规范
变量
1本地变量
1.1普通变量
变量调用格式:echo $变量名
用途:调用变量,若有值,表示有此变量名和变量值
定义方式一:变量名=变量值
注:变量值需是一个整体,中间不能有特殊字符
定义方式二:变量名=‘变量值’
注:’ '内有什么内容,输出什么内容
定义方式三:变量名=“变量值”
注:可输出" "内包含的变量,解析->赋值
示例:
1.2命令变量
执行`或者$( )范围内的命令,并将命令执行的结果赋值给新的变量名
方式一:变量名=`命令`
`为反引号
示例:
dir = `pwd`
echo $dir
/root
方式二:变量名=$(命令1)
变量名=$(命令)
示例:
dir = $(pwd)
echo $dir
/root
2全局变量
当前系统环境下都能生效的变量
命名一般大写
注:全局变量(即环境变量)在当前整个Shell会话及其派生出的任意子Shell中都有效,另外需要注意的是,环境变量只能向下传递而不能向上传递,即“传子不传父”。每个定义里的Shell会话都有自己的作用域,彼此之间互不影响。
2.1查看全局变量命令
env(enver) 显示全局变量
env | grep 全局变量名
2.2定义
方法一:
变量 = 值
export 变量
方法二:export 变量名=值 (常用)
3变量的查看和取消
3.1变量的查看
方式一:$变量名
方式二:"$变量名"
方式三:${变量名}
方式四:"${变量名}"
方法四为标准使用方式 ,可解析变量
3.2变量的取消
命令:unset 变量名
4shell内置变量
4.1和脚本相关的
$0
自动获取当前脚本相关的文件名
$n
获取脚本传入的第n个位置的参数
示例:
$#
获取当前脚本传入参数的数量
$?
获取执行上一个指令的返回值(判断上一个指令是否成功)(0为成功,非0为失败)
4.2字符串精确截取
格式:#{变量名:起始位置:截取长度}
4.3默认值
4.3.1有条件的默认值
命令:${变量名:-默认值}
变量若有值输出变量值,若变量没值,输出默认值
示例:
4.3.2无条件的默认值
格式:${变量名+默认值}
无论变量是否有值,都输出默认值
表达式(测试语句 )
1条件表达式
形式一:test 条件表达式
test 1 = 2
echo $?
1
形式二:[ 条件表达式 ]
注1:0为成功,非0为失败($?)
注2:常用 形式二
注3:两侧空格表示分隔,表示与[]不是一个整体
2逻辑表达式 && 和||
&&
格式:命令1 && 命令2
注释:命令1成立,执行命令2;命令1失败,不执行命令2 (跟风)
||
格式:命令1 || 命令2
注释:命令1成立,不执行命令2;命令1失败,执行命令2 (替补)
3文件表达式
-f 判断是否是一个普通文件
-d 判断是否是一个目录
-x 判断输入的内容是否有执行权限
4数字
n1 -eq n2 #等于 #equal
n1 -gt n2 #大于
n1 -ge n2 #大于等于
n1 -lt n2 #小于
n1 -le n2 #小于等于
n1 -ne n2 #不等于 #not equal
示例:
[ 1 -eq 2 ]
[ 1 -ne 2 ]
5字符串
str1 == str2 #str1和str2字符串内容一致
str1 != str2 #str1和str2字符串内容不一致
示例:
[ a == a ]
[ a == ab ]
a = nihao
b = buhao
[ "${a}"=="${b}" ]
echo $?
1
6计算表达式
方式一: $(())
$((计算表达式))
注:只能计算整数 bc可计算浮点数
$((2+2))
i=1
i=$((i+7))
echo $i
方式二: let
常见符号
1重定向符号
>
将左侧内容以覆盖的方式输入右侧文件
示例:
echo "nihao">file1.txt
>>
将左侧内容以追加的方式输入右侧文件末尾
2管道符
格式:命令1 | 命令2
命令1的内容传给右侧命令2使用
3其他符号
格式:命令 &
将一个命令从前台转到后台
4全部信息符号
格式:2>&1
表示所有输出的信息
注:1 表示正确输出的信息
选择文件中正确执行的信息输出
2 表示错误输出的信息
选择文件中错误未执行的信息输出
示例:
bash ceshi.sh 1>> ceshi-ok 2>>ceshi-err
cat ceshi-ok
cat ceshi-err
bash ceshi.sh 1>> ceshi-ll 2>>ceshi-ll
cat ceshi-ll
bash ceshi.sh >> ceshi-all 2>&1
cat ceshi-all
5linux系统垃圾桶
格式:/dev/null
Linux中的设备文件 相当于垃圾桶
示例:
bash ceshi.sh >> /dev/null 2>&1
常见命令
1 grep
文本搜索命令
格式:grep 参数 关键字 文件名
示例:
grep -c aaa grep.txt
拓展:grep -nr 错误关键字 *
可精确定位错误代码
2 sed
行文件编辑工具
格式:sed 参数 ‘<匹配条件>[动作]’ 文件名
2.1sed替换
格式:sed -i 替换格式 文件名
注1:替换命令的写法
‘s###’ -> ‘s#原内容##’ ->‘s#原内容#替换后内容#’
注2:#是关键字隔离符号
注3:#可以换成@、/、!
实例格式:sed -i ‘行号s###列号’ 文件名
注1:列号不加,默认为第行第一个
注2:指定一行为:行号$
注3:指定范围为:行号,行号
注4:指定全部为:列号g
注5:指定行的全部为:行号+g
示例:
2.2sed增加
2.2.1 -a
在指定行号的下一行增加内容
格式:sed -i ‘行号a\增加的内容’ 文件名
注意:若想增加多行,在行号位置写范围值,即两个行号见逗号隔开:
多行格式:sed -i ‘行号,行号a\增加的内容’ 文件名
2.2.2 -i
在指定行号的上一行增加内容
格式:sed -i ‘行号i\增加的内容’ 文件名
注意:若想增加多行,在行号位置写范围值->两个行号见逗号隔开:
多行格式:sed -i ‘行号,行号i\增加的内容’ 文件名
2.3sed删除
指定行号删除 #-d
格式:sed -i ‘行号d’ 文件名
注意:若想删除多行,在行号位置写范围值->两个行号见逗号隔开:
多行格式:sed -i ‘行号,行号d’ 文件名
3 awk
文档编辑工具
3.1awk
格式:awk 参数 ‘动作’ 文件名
示例:
awk '{print $1}' awk.txt
3.2指定分隔符
-F指定分隔符 -F ‘指定分隔符’ ‘{动作}’ 文件名
注:默认列的分隔符是空格
示例:
awk -F ':' '{print $2,$3}' awk.txt
3.3OFS
设置显示分隔符
awk 'BEGIN{OFS=":"}{print$n1,$n3}' awk.txt
输出:
列n1:列n3
4 fing
查找文件
格式:find 路径 参数 关键字("文件名 ")
示例:
find /home/ -name "*.txt"
find /home/ -type f
find /home/ -type f -name "get_*"
流程控制
1简单流程控制语句
1.1单分支if语句
格式:
if [ 条件 ]
then
指令
fi
1.2 双分支if语句
格式:
if [ 条件 ]
then
指令1
else
指令2
fi
1.3多分支if语句
格式:
if [ 条件1 ]
then
指令1
elif [ 条件2 ]
then
指令2
else
指令3
fi
案例:
vim duoif_serv.sh
cat duoif_serv.sh
#!/bin/bash
#多if语句的使用场景
if [ "$1" == "start" ]
then
echo "服务启动中..."
elif [ "$1" == "stop" ]
then
echo "服务关闭中..."
elif[ "$1" == "restart" ]
then
echo "服务重启中..."
else
echo "$0 脚本的使用方式:$0 [ start | stop | restart ]"
fi
bash duoif_serv.sh stop
"服务关闭中..."
1.4case语句
格式:
case 变量名 in
值1)
指令1
;;
值2)
指令2
;;
值3) # *) *==else
指令3
;;
esac
1.5for循环语句
格式:
for 值 in 列表
do
执行语句
done
1.6while循环语句
条件满足循环,不满足退出
格式:
while 条件
do
执行语句
done
1.7until语句
条件不满足循环,满足退出
格式:
until 条件
do
执行语句
done
2复杂流程控制语句
2.1函数定义与调用
格式:
定义函数:
函数名(){
函数体
}
调用函数:
函数名
2.2传参函数定义与调用
格式:
定义函数:
函数名(){
函数体 $n
}
调用函数 传参数:
函数名 参数
综合案例
启动服务脚本
1 #!/bin/bash
2 #综合案例
3
4 #定义本地变量,接受脚本传参
5 a="$1"
6
7 #编写脚本帮助信息
8 help(){
9 echo "脚本$0 使用方式$0 [ start|stop|re start ]"
10 }
11
12 if [ "$#" -eq 1 ]
13 then
14 case "${a}" in
15 start)
16 echo "服务启动中..."
17 ;;
18 stop)
19 echo "服务关闭中..."
20 ;;
21 restart)
22 echo "服务重启中"
23 ;;
24 *)
25 help
26 ;;
27 esac
28 else
29 help
30 fi
新建用户脚本
1 #!/bin/bash
2
3 # user_name 用来保存第一个脚本参数 用户名
4 user_name="$1"
5 # user_group 用来保存第二个脚本参数 组名
6 user_group="$2"
7
8 #判断脚本参数个数 如果大于1或大于2 给予提示信息
9 if [ $# -lt 1 ] || [ $# -gt 2 ]
10 then
11 echo "运行脚本的方式为:bash $0 user_name [group_name]"
12 # 终止脚本
13 exit
14 else
15 # 如果参数个数满足1或者2,那么判断一下是否有组名,如果没有的话把用户名复
制给组名
16 [ "${user_group}" == '' ] && user_group=$user_name
17 fi
18
19 # 判断用户是否存在 把输出的结果扔到垃圾桶
20 id $user_name > /dev/null 2>&1
21
22 # 如果上一个命令执行失败,则没有该用户,需要创建
23 if [ $? -ne 0 ]
24 then
25 echo "不存在用户${user_name},准备新建用户..."
26 # 创建用户之前还需要判断组是否存在
27 cat/etc/group | grep ${user_group} > /dev/null 2>&1
28 # 如果上一个命令没有查到当前组名,则需要新建组名
29 if [ $? -ne 0 ]
30 then
31 sudo groupadd ${user_group}
32 echo "${user_group}组创建成功..."
33 fi
34 sudo ueradd -m -g ${user_group} ${user_name}
35 echo "用户新建成功,请为新用户设置密码..."
36 sudo passwd ${user_name}
37 echo "用户${user_name}新建完成..."
38 else
39 echo "用户${user_name}已经存在..."
40 fi