Linux系统中的Shell脚本是一个特殊的应用程序,它介于操作系统内核与用户之间,充当一个“命令解释器”的角色,负责接收用户输入的操作指令(命令)并进行解释,将需要执行的操作传递给内核执行,并输出执行结果。
shell 控制Linux内核,内核态会加载系统硬件提供支持,然后输出信息 (结果、bug、err)
shell 也可以通过控制应用程序,再进行控制Linux内核
应用程序(例如kickstart 无人值守)
内核放在boot中,boot还存放的GRUB菜单
登录后默认使用的Shell程序,一般为/bin/bash
不同的Shell的内部指令,运行环境等会有所区别
示例:
[root@localhost ~]# cat /etc/shells
/bin/sh
/bin/bash
/sbin/nologin
/usr/bin/sh
/usr/bin/bash
/usr/sbin/nologin
/bin/tcsh
/bin/csh
示例:
[root@localhost ~]# vi first.sh
#!/bin/bash
cd /boot/
pwd
ls -lh vm*
#!/bin/bash :代表固定格式,相当于声明
cd /boot :跳转到boot目录
pwd :显示目前所在工作环境的目录
ls -lh vm* :长格式友好显示(带有单位)以vm开头的所有文件。
注意!在执行脚本前我们要养成赋予脚本可执行权限的习惯
示例:
[root@localhost ~]# chmod +x first.sh
[root@localhost ~]# ls -l
-rwxr-xr-x. 1 root root 37 Nov 25 22:22 first.sh
.....省略部分内容
执行脚本的四种方式:
方法一:脚本文件路径(绝对路径与相对路径)
[root@localhost ~]# ./first.sh
此方法需要赋予执行权限
方法二:sh 脚本文件路径
[root@localhost ~]# sh first.sh
此方法不要求脚本拥有执行权限,但如果脚本中执行了切换位置的命令,此方式不会进行切换。
方法三:source 脚本文件路径
[root@localhost ~]# source first.sh
此方法也不要求脚本拥有执行权限,但若脚本中执行了切换位置的命令,此方式同样会进行切换。
方法四:"." 的使用
[root@localhost ~]# . first.sh
此方式与方法三类似,但就生产环境而言,我们一般不会使用此方式。
示例:
#!/bin/bash
#这是我的第一个脚本.
cd /boot/
echo "当前的目录位于:"
pwd
echo "其中以vm开头的文件包括:"
ls -lh vm*
~
执行脚本:
[root@localhost ~]# sh first.sh
当前的目录位于:
/boot
其中以vm开头的文件包括:
-rwxr-xr-x. 1 root root 5.7M Nov 25 19:07 vmlinuz-0-rescue-0c76c4a5ba044cb8a81c079681ade901
-rwxr-xr-x. 1 root root 5.7M Aug 23 2017 vmlinuz-3.10.0-693.el7.x86_64
**格式:**cmd1 | cmd2 [… | cmdn]
示例:
[root@localhost ~]# grep "login$" /etc/passwd | awk -F: '{print $1,$7}'
bin /sbin/nologin
daemon /sbin/nologin
adm /sbin/nologin
lp /sbin/nologin
.......省略部分内容
awk -F: ‘{print $1,$7}’ 输出第一列与第七列
awk -F : 以":"分割
**{print $1,$7}:**位置变量统计
如果awk不加参数,只加段落内容,系统将默认按空格和tab(制表符)进行分割
变量名以字母或下划线开头,区分大小写,建议全部大写
变量名=变量值
“=” 为赋值符号,代表把赋值符号右边的内容赋予给左边的变量名
变量名的命名,以字母或者下划线开头,例如:
addr="192.168.100.100";
命名时,要么以字母开头,要么以”_“开头,例如:
_abc="hello"
不能以123abc=”world“;此格式进行命名
在输出时,需要在变量名前加上$符号
示例:
[root@localhost ~]# addr=192.168.100.100
[root@localhost ~]# echo $addr
192.168.100.100
PS:所有变量会存储在内存中,内存中的数据并不稳定(例如关机后会丢失)
此处需要注意:
如果重新赋予新的值,那么命名的值会更新(覆盖)
示例:
[root@localhost ~]# addr=192.168.100.100
[root@localhost ~]# echo $addr
192.168.100.100
[root@localhost ~]# addr=10
[root@localhost ~]# echo $addr
10
变量名对应的赋予值会独立存储
示例:
[root@localhost ~]# addr=192.168.100.100
[root@localhost ~]# echo $addr
192.168.100.100
[root@localhost ~]# addr=10
[root@localhost ~]# echo $addr
10
[root@localhost ~]# num=$addr
[root@localhost ~]# addr=20
[root@localhost ~]# echo $num
10
[root@localhost ~]# echo $addr
20
从以上信息我们可以得知,变量名在被赋予变量值后,会单独存储在一份空间,并不会随着之后的变量值更改而更改。
允许同时输出两个变量
示例:
[root@localhost ~]# echo $addr $num
20 10
[root@localhost ~]#
赋值时使用引导
从键盘输入内容为变量赋值
read [-p "提示信息"] 变量名
反撇号”`“ 命令替换,提取命令执行后的输出结果
示例:
[root@localhost opt]# ps aux | wc -l
188
[root@localhost opt]# num=`ps aux | wc -l`
[root@localhost opt]# echo $num
189
[root@localhost opt]# abc=$(ps aux | wc -l)
[root@localhost opt]# echo $abc
189
read [-p “提示信息”] 变量名
示例一:
#!/bin/bash
echo "请输入你的成绩"
read score
echo "你的成绩为$score"
示例二:
你的成绩为12
#!/bin/bash
read -p "请输入你的成绩" score
echo "你的成绩为$score"
---->wq
[root@localhost opt]# ./demo.sh
请输入你的成绩12
你的成绩为12
命令格式1:export 变量名
格式2:export 变量名=变量值
两种格式可以混用
expr 变量1 运算符 变量2 [运算符 变量3]…
例如:
[root@localhost opt]# expr 3 + 2
5
[root@localhost opt]# expr 3 - 2
1
[root@localhost opt]# expr 3 \* 2
6
[root@localhost opt]# expr 3 % 2
1
[root@localhost opt]# sum=`expr 3 + 3`
[root@localhost opt]# echo $sum
6
环境变量
由系统提前创建,用来设置用户的工作环境
配置文件: /etc/profile、~/.bash_profile
常见的环境变量
PWD、PATH
USER、SHELL、HOME
示例:
[root@localhost opt]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
位置变量
位置表示为$n,n为1~9之间的数字
例如:
[root@localhost opt]# ./demo.sh one two three four five six
以上示例中 ./demo.sh 为$0 one为$1 一次类推
示例:
[root@localhost opt]# vi demo01.sh
#!/bin/bash
sum=0
sum=`expr $1 + $2`
echo "总和为$sum"
echo "执行的脚本数为$0"
echo "参数格式为$#"
------->wq
[root@localhost opt]# ./demo01.sh 10 20
总和为30
执行的脚本数为./demo01.sh
参数格式为2
预定义变量
$#:命令行中位置变量的个数
$*:所有位置变量的内容
$?:上一条命令执行后返回的状态,当返回状态值为0时表示执行正常,非0值表示执行异常或出错
$0:当前执行的进程/程序名
示例:
[root@localhost opt]# vi demo02.sh
#!/bin/bash
TARFILE=beifen-`date +%s`.tgz
tar zcf $TARFILE $* &> /dev/null
echo "已执行$0脚本"
echo "共完成$#个对象的备份"
echo "具体内容包括:$*"
--------》wq
[root@localhost opt]# chmod +x demo02.sh
[root@localhost opt]# ./demo02.sh /etc/passwd /etc/shadow
已执行./demo02.sh脚本
共完成2个对象的备份
具体内容包括:/etc/passwd /etc/shadow
预定义变量
$#:命令行中位置变量的个数
$*:所有位置变量的内容
$?:上一条命令执行后返回的状态,当返回状态值为0时表示执行正常,非0值表示执行异常或出错
$0:当前执行的进程/程序名
示例:
[root@localhost opt]# vi demo02.sh
#!/bin/bash
TARFILE=beifen-`date +%s`.tgz
tar zcf $TARFILE $* &> /dev/null
echo "已执行$0脚本"
echo "共完成$#个对象的备份"
echo "具体内容包括:$*"
--------》wq
[root@localhost opt]# chmod +x demo02.sh
[root@localhost opt]# ./demo02.sh /etc/passwd /etc/shadow
已执行./demo02.sh脚本
共完成2个对象的备份
具体内容包括:/etc/passwd /etc/shadow
Shell脚本变成规范与变量是我们学习的基础,我认为在写Shell脚本的过程中,我们尤为需要注重:
1、Shell脚本中需空格的部分
2、撇、双引号、单引号、小括号、中括号和大括号的用法
对于三种括号的用法,小结以下技巧:
字符串比较用双中括号 [[ ]] ;算数比较用单中括号 [ ] ----左右需留空格
算数运算用双小括号(( ));Shell命令及输出用小括号( )-------左右不需要留空格
快速替换用大括号 { }------左右需留空格
反单引号起着命令替换的作用(ESC下方的键)
3、打“引号”的时候,输入法最好统一(中、英文输入法)