shell基础
shell基础
概述
bash: 是一个为GNU计划编写的Unix shell,是许多Linux发行版的默认Shell
shell:当命令或程序语句不在交互式命令行下执行,而是通过一个程序文件来执行时,该程序就可以被称为脚本。在shell脚本中写入命令、变量、语句、及流程控制语句,然后将这些命令一次性执行完毕,这种批量执行命令的方式被称为非交互式的方式。
shell在生产环境中常被用于:软件一键自动化安装、优化,监控报警、软件启动、日志分析等。由于shell与linux关系密切,因此更加适合通过shell脚本语言来帮助用户实现轻松、高效的运维任务。
执行方式
执行方式 | 描述 |
---|---|
bash test.sh | 以bash启动脚本 |
sh test.sh | 以sh启动脚本 |
./test.sh | 需要文件拥有X权限,在当前路径下启动脚本 |
. test.sh | 需要文件拥有X权限,在当前路径下启动脚本 |
注意:最后两种方式执行脚本时会加载并执行相关脚本文件中的命令及语句,而不是产生一个子shell来执行文件中的命令。
其他方式在执行时都会生成一个新的子进程执行。
重定向:
标准输入(STDIN):默认的设备为键盘,文件编号为0,命令将从标准输入文件中读取在执行过程中需要的输入数据
标准输出(STDOUT):默认的设备为显示器,文件编号为1,命令将执行后的输出结果发送到标准输出文件
标准错误(STDERR):默认的设备是显示器,文件编号为2,命令将执行期间的各种错误信息发送到标准错误文件
在实际操作中,可以改变输入、输出内容的方向,而不是使用默认的标准输入输出的设备(键盘、显示器),这种操作称为“重定向”
符号
符号 | 描述 |
---|---|
> | 重定向输出,覆盖文件内容 |
>> | 重定向输出,叠加文件内容 |
< | 重定向输入 |
2> | 错误重定向,覆盖,将错误信息重新定义到新的文件中 |
2>> | 错误重定向,追加,将错误信息重新定义到新的文件中 |
管道操作
查询以bash结尾的行
# grep "bash$" /etc/passwd
查询以bash结尾的行并只显示这一行的第一列与第七列字符,字符以":"分界
# grep "bash$" /etc/passwd | awk -F: '{print $1,$7}'
表示只查询/分区的磁盘使用百分比
# df -TH | grep "/$" | awk '{print $6}' | awk -F% '{print $1}'
变量
所有的编程语言都利用变量来存放数据,以备后续使用或者修改。
和编译型语言不同,大多数脚本语言不要求在创建变量之前声明其变量类型,用到什么类型就是什么类型。
在变量名前面加上一个美元符号就可以访问到变量的值,shell定义了一些变量,用于保存用到的配置信息,比如可用的打印机、搜索路径等,这些变量叫作环境变量。
变量名由一系列字母、数字、下划线组成,其中不包括空白字符,常用惯例是在脚本中使用大写字母为环境变量命名,或者使用驼峰命名法和小写字母为其他变量命名
简单地说:变量就是用一个固定的字符串(字母、数字、符号等组合)代替更多、更复杂的内容。在使用这些更多、更复杂内容时,通过简短固定的变量命来代替。
注意:
- 可通过"set"查看当前linux系统中的所有变量
- 可通过"env"查看当前linux系统中的全局变量
变量类型
变量分为环境变量(全局变量)和普通变量(局部变量)。
环境变量可以创建在他们的shell及子shell中使用,环境变量又分为自定义变量和bash内置环境变量。
普通变量只能在创建他们的shell函数或shell脚本中使用,普通变量一般由开发者在开发脚本程序时创建。
自定义变量
三种方式:
- export 变量名=变量值
- 变量名=变量值;export 变量名
- declare -x 变量名=变量值
撤销变量:unset
设置变量的作用范围
默认情况下,新定义的变量只能够在当前的shell环境使用,这也叫局部变量,当进入一个新的shell环境后将不能使用局部变量。
使用export将局部变量设置为全局变量:
- export product version //直接将局部变量转换为全局变量
- export product=Test //在变量赋值时进行设置为全局变量
引号的使用
赋值时使用引号
双引号:允许通过$符号引用其他变量值
单引号:禁止引用其他变量值,$视为普通字符
反撇号:命令替换,提取命令执行后的输出结果
将执行某个命令的屏幕输出结果赋值给变量,并通过命令进行处理,如下:
例如:
# ls -l `which useradd` //此命令含义为:先执行反撇号中的内容,也就是查询useradd的位置,然后使用ls -l进行查看
特殊的shell变量
1、环境变量
env //查看当前工作环境的环境变量
PATH变量用于设置可执行程序默认搜索路径
2、位置变量
$n:n为自然数。0代表命令本身,1到9代表第1到第9个参数(参数的值是执行该命令时,从1开始依次输入的),10以上的参数要用大括号包含,如${10}。
# vim sum.sh
a=`expr $1 + $2`
echo "$1 + $2 = $a"
# ./sum.sh 2 4
2 + 4 = 6
或者以下表示方法:
# vim sum.sh
a=$[$1 + $2]
echo "$1 + $2 = $a"
3、预定义变量
$#:命令行中位置变量的个数
$*:所有位置变量的内容
$?:上一条命令执行后返回的状态,当返回状态值为0时表示执行正常,非0值表示执行异常或出错
$0:当前执行的进程/程序名/脚本
举例:
\# cd /boot
\# echo $? //返回结果为0表示上一条命令执行成功
\# cds /boot
\# echo $? //这次返回结果范围为1-255.表示上一条命令执行错误
\# vim mybak.sh
\#!/bin/bash
Backup=beifen-`date +%s`.tar.gz
tar zcf $Backup $* &> /dev/null
echo "已执行 $0 脚本,"
echo "共完成 $# 个对象的备份"
echo "具体内容包括: $*"
# ./mybak.sh /etc/passwd /etc/shadow
已执行 ./mybak.sh 脚本,
共完成 v2 个对象的备份
具体包括:/etc/passwd /etc/shadow
环境变量初始化与对应文件的生效顺序
在登录Linux系统并启动一个bash shell时,默认情况下bash会在若干个文件中查找环境变量的设置。这些文件可统称为系统环境变量文件。
Bash检查的环境变量文件的情况取决于系统运行shell的方式。
系统运行shell的方式一般有三种:
- 通过系统用户登录和默认运行的shell。
- 非登录交互式运行shell
- 执行脚本运行非交互式shell
当用户登录Linux系统时,shell会作为登录shell启动。此时的登录shell加载环境变量的顺序如图:
用户登录系统后会首先加载/etc/profile全局环境变量文件,这是Linux系统上默认的shell主环境变量文件。系统上每个用户登录都会加载该文件。
当加载该文件后,才会执行/etc/profile.d目录下的脚本文件,这个目录下的脚本文件有很多,如:系统的字符集设置(/etc/sysconfig/il8n)等。
之后开始运行$HOME/.bash_profile(用户环境变量文件),在这个文件中,又会去找$HOME/.bashrc(用户环境变量文件),如果有,则执行。之后执行/etc/bashrc(全局环境变量文件)有就执行,没有则不执行。
如果用户的shell不是登录时启动的,(比如在登录界面中敲入bash进入新的子shell环境)那么这种非登录shell就只会加载$HOME/.bashrc,之后加载/etc/bashrc。如果希望在非登录shell下也可读到设置的环境变量内容,就需要将变量设置写入到$HOME/.bashrc或者/etc/bashrc。而不是$/HOME/.bash_profile或/etc/profile。
条件测试操作
文件测试
参数 | 描述 |
---|---|
-d | 检测是否为目录 |
-e | 检测目录或文件是否存在 |
-f | 检测是否为文件 |
-r | 测试当前用户是否有权限读取 |
-w | 测试当前用户是否有权限写入 |
-x | 测试当前用户是否有权限执行 |
# [ -d /boot ] //-d表示目录,
# echo $? //结果表示为0表示/boot目录存在
# [ -d /boota ] //输入一个不存在的目录
# echo $? //结果表示为1,说明上一条命令执行错误
当测试条件成立时,接着执行&&后面的内容:
# [ -e /root ] && echo "该路径存在!"
该路径存在!
整数值比较
参数 | 描述 |
---|---|
-eq | 第一个数等于第二个数 |
-ne | 第一个数不等于第二个数 |
-gt | 第一个数大于第二个数 |
-lt | 第一个数小于第二个数 |
-le | 第一个数小于或等于第二个数 |
-ge | 第一个数大于或等于第二个数 |
e | 等于 |
n | 不等于 |
l | 小于 |
g | 大于 |
判断第一个数小于第二个数
[ $(who | wc -l) -eq 5 ] && echo "当前登录用户数量为5个!"
通过比较并输出剩余内存值
# Free=`free -m | grep "Mem" | awk '{print $4}'` //以M为单位查询
# [ $Free -lt 1024 ] && echo "当前系统剩余内存为${Free}MB"
976MB
字符串比较
参数 | 描述 |
---|---|
= | 第一个字符串是否与第二个字符串相同 |
! | 第一个字符串与第二个字符串不相同, ! 表示取反 |
-z | 检查字符串是否为空,对于未定义或赋予空值的变量将视为空串 |
举例:判断当前系统语言环境
# [ $LANG != "en.US" ] && echo "Not en.US"
逻辑测试
参数 | 描述 | ||
---|---|---|---|
&& | 逻辑与,相当于“而且”只有当前后两个条件都成立,整个测试命令返回值为0,表示成立 | ||
\ | \ | 逻辑或,相当于“或者”只要前后两个条件有一个成立,整个测试命令返回值为0,表示成立 | |
! | 逻辑否,表示“不” 只有当前指定的条件不成立时,整个测试命令的返回值才为0 |
举例,查看内核版本是否大于2.4
# Uname1=$(uname -r | awk -F. '{print $1}')
# Uname2=$(uname -r | awk -F. '{print $2}')
# [ $Uname1 -eq 3 ] && [ $Uname2 -gt 4 ] && echo "版本大于3.4,版本号为:${Uname1}.${Uname2}"
版本大于2.4,版本号为:2.6
当第一个判断和第二个判断有一个成立时,都执行echo中的内容:
# [ $Uname1 -eq 2 ] || [ $Uname2 -gt 4 ] && echo "版本大于2.4,版本号为:${Uname1}.${Uname2}"
如果第一个和第二个判断都不成立,则不执行echo中的内容:
# [ $Uname1 -eq 2 ] || [ $Uname2 -gt 44 ] && echo "版本大于2.4,版本号为:${Uname1}.${Uname2}"
本文系作者 @小白学安全 原创发布在 xbxaq.com 站点,未经许可,禁止转载!
评论