shell 1

shell

是在Linux内核与用户之间的解释器程序
通常指/bin/bash
负责向内核翻译及传达用户/程序指令
相当于操作系统的“外壳”

shell的使用方式
交互式 ----命令行
人工干预,智能化程度高
效率低

非交互式 ----脚本
需要提前设计,智能化难度大
效率高,批量执行
方便在后台静悄悄的运行
------------------------------------------------
如何切换shell环境
通过usermod,chsh更改登陆shell
手动执行目标shell程序

# cat /etc/shells
/bin/sh #多数unix默认的shell。在rhel系统中,实际上sh是bash的符号链接
/bin/bash #多数linux默认使用的shell
/sbin/nologin #非登陆shell
/usr/bin/sh
/usr/bin/bash
/usr/sbin/nologin
/bin/tcsh
/bin/csh
/bin/ksh
----------------------------------------
bash基本特性

命令行环境回顾
快捷键,tab键补齐
命令历史
命令别名
标准输入输出
重定向
管道操作
-------------------------------------
历史命令

存放位置及数量
默认记录1000条

历史记录保存在这个文件里:~/.bash_history

控制历史命令的数量:
# grep ^HISTSIZE /etc/profile
HISTSIZE=1000 #全局设置的记录个数
-------------------------------------------
操作历史命令
history #查看历史命令
history -c #清空历史命令

调用历史命令
!78 #执行历史记录中的第78条命令
!str #执行最近一次以str开头的历史命令
------------------------------------------------
I/O设备与重定向

交互式硬件设备
标准输入:从该设备接收用户输入的数据
标准输出:通过该设备向用户输出数据
标准错误:通过该设备报告执行行中的出错信息

类型 设备文件 文件描述号 默认设备
标准输入 /dev/stdin 0 键盘
标准输出 /dev/stdout 1 显示器
标准错误输出 /dev/stderr 2 显示器
---------------------------------------------------
重定向

改变标准输入/输出/错误输出的方向
重定向输入 < 将文本输入来源由键盘改为指定的文件
重定向输出 > 将命令行的正常执行输出保存到文件,而不是直接显示在屏幕上
>> 与>类似,但操作是追加而不是覆盖
重定向错误 2> 将命令行的执行出错信息保存到文件,而不是直接显示在屏幕上
2>> 与2>类似,但操作是追加而不是覆盖
混合重定向 &> 相当于>和2>,覆盖到同一个文件
---------------------------------------------------
shell脚本

是提前写好可执行语句,能够完成特定任务的文件。
顺序,批量化处理
解释型程序
----------------------------------------------------
脚本创建“三步走”

1,新建文本文件
2,添加可执行的脚本语句(命令行)
3,添加x执行权限

vim /root/first.sh

#!/bin/bash

echo 'Hello World'

# chmod +x /root/first.sh
# /root/first.sh
Hello World
-------------------------------------------------------
规范的脚本构成

#! 脚本声明(使用哪种解释器)
#注释信息(步骤,思路,用途,变量含义等)
可执行的语句

在屏幕上输出一段文字“
vim /root/first.sh
#!/bin/bash #Sha-Bang调用标记
#A test program for Shell-Script #注释信息
echo “Hello World” #可执行的脚本语句或命令行

#Description:描述
#version:2.0
------------------------------------------------------------
脚本的执行方式

方法一,作为“命令字”
指定脚本文件的路径,前提是由x权限

方法二,作为“参数”,不要求x权限
sh 脚本文件路径
source 脚本文件路径
. 脚本文件路径

# sh /root/first.sh
Hello World
# . /root/first.sh
Hello World
------------------------------------------------------------
调式shell脚本

作用:
直接观察执行中的输出,报错信息
通过 sh -x 开启调试模式
在可能出错的地方设置echo

# sh -x /root/first.sh
+ echo 'Hello World'
Hello World
--------------------------------------------------------------
快速创建用户user0到10,并设置密码

# cat /root/test.sh
#!/bin/bash
> /root/user.log #先清空这个文件
for i in {1..10}
do
useradd user$i 2>> /root/user.log #只有一个 > 会覆盖之前的错误,不方便我们后续排查
echo '123' | passwd --stdin user$i > /dev/null #进行到这一步只会是正确的信息
done
---------------------------------------------
为本机快速配好yum仓库

vim /root/yum.sh

#!/bin/bash

rm -rf /etc/yum.repos.d/* #先清空配置目录,防止错误配置文件影响正确配置文件
echo "[http]
name=rhel7.0
baseurl=http://172.25.254.254/content/rhel7.0/x86_64/dvd/
gpgcheck=0" > /etc/yum.repos.d/rhel7.repo
yum clean all &> /dev/null
yum repolist | tail -3
--------------------------------------------------
为本机快速搭建vsftpd服务

为新装的客户机搭好vsftpd服务
装包,起服务,设开机自动运行,通过脚本来实现这些操作

vim /root/ftp.sh
yum -y install vsftpd &> /dev/null #装包,忽略输出
systemctl restart vsftpd #起服务
systemctl enable vsftpd #开机自启
---------------------------------------------------
变量

以固定名称存放,可能会变化的值
提高脚本对任务需求,运行环境变化的适应能力
方便在脚本中重复使用

定义/赋值变量
变量名=变量值

# a=12
# echo $a
12
---------------------------------------------------
若指定的变量名已存在,相当于为此变量重新赋值
等号两边不能有空格
变量名只能由字母,数字,下划线组成,区分大小写。
变量名不能以数字开头,不要使用关键字!
变量名里面不能有特殊符号!
所以它能识别$a.b $a-b $a b
-------------------------------------------------
查看变量
引用变量值:$变量名
查看变量值:echo $变量名
echo ${变量名}
-------------------------------------------------
# a=11
# b=22
# echo $a
11
# echo $b
22
# echo $a$b
1122
# echo $ab #未定义的变量无取值,输出为空

# echo ${a}b
11b
# echo $a.b
11.b
# echo $a-b
11-b
# echo $a b
11 b
# echo $a,$b,$c
11,22,33
-----------------------------------------------
x=12
#echo $x
12
var1=centos
# echo $var1
centos
# echo $x,$var1
12,centos
# echo ${var1}6.5 #变量名容易混淆时,以{}界定
centos6.5
# echo $var16.5 #未定义的变量无取值,输出为空
.5
-------------------------------------------------
取消变量名
unset 变量名 ...

退出定义变量的shell环境时,变量会自动失效
可以手动取消
unset 变量名 ...

取消变量名a
unset a

unset x
# echo $x #未定义的变量无取值,输出为空
---------------------------------------------------
系统环境变量名默认大写
配置文件:/etc/profile,~/.bash_profile
----------------------------------------------------
相关操作:

env
列出所有环境变量。能显示计算机的所有大写的,自带的环境变量命令。
--------------------------------------------------
set
列出所有变量。能显示计算机的所有环境变量命令,包括自己设置的变量。很多,所以一般最好和管道grep一起用

abcd=1234
set | grep abcd #显示包含abcd的环境变量
-------------------------------------------------------
常见的环境变量
PWD, PATH, USER, LOGNAME, UID, SHELL, HOME, PS1, PS2
--------------------------------------------
# echo $USER #当前用户
root
# echo $UID #当前用户id
0
# echo $HOME #当前用户家目录
/root
# echo $PWD #当前用户位置
/etc
# echo $SHELL #当前用户解释器
/bin/bash
# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
-------------------------------------------------
${10}
变量大于9了,要加上花括号
--------------------------------------------------
$0 当前所在的进程或者脚本名
$* 列出所有的参数
$# 所有参数一共多少个
$$ 当前进程的进程号PID
$? 命令执行后的返回状态,检查上条命令是否正确。0代表对,1或其他值表示异常
---------------------------------------------------------
环境变量 PWD, PATH, USER, LOGNAME, UID, SHELL, HOME, PS1, PS2
预定义变量 $0 ,$*,$#,$$ ,$?
位置变量 $1 ,$2 ,${10}

# vim /root/1.sh
#!/bin/bash
echo $0 //脚本的名称
echo $1 //第一个参数
echo $2 //第二个参数
echo $* //所有参数
echo $# //所有的综合
echo $$ //当前进程的进程号
echo $? //上一个程序的返回状态码


$$ 保存当前运行进程的(PID)号
$? 保存命令执行结果的(返回状态)
$0 保存当前运行的(进程名)或(脚本名)
$# 保存位置变量的(个数)
$* 保存所有位置变量的(值)
$! 保存后台(最后一个进程)的PID号

# chmod +x /root/1.sh //添加可执行权限

# /5.sh 1 2 a b c
/5.sh
1
2
1 2 a b c
5
6670
0
------------------------------------------------------
ps abcd
查看abcd 这个变量的进程号
---------------------------------------------------
# vim /root/9.sh
#!/bin/bash

useradd $1
echo $2 | passwd --stdin $1

# chmod +x /root/9.sh
# /root/9.sh dc 123
更改用户 dc 的密码 。
passwd:所有的身份验证令牌已经成功更新。

# mv /root/9.sh /bin #可以在任何目录下运行这个脚本
# 9.sh haha 1
更改用户 haha 的密码 。
passwd:所有的身份验证令牌已经成功更新。
--------------------------------------------------------------
双引号"" 允许扩展,以$引用其他变量
单引号'' 进制扩展,即便$也视为普通字符
反撇号`` 将命令的执行输出作为变量值

单引号和双引号的区别: 都是能够界定一个完整的字符串,但是单引号能屏蔽特殊符号的功能!

# echo "当前用户是:$USER"
当前用户是:root
# echo '当前用户是:$USER'
当前用户是:$USER
# echo 当前用户是:$(pwd)
当前用户是:/root

$()与``等效,但$()更方便嵌套使用
----------------------------------------------
# mkdir test
# cd test
# ls
# touch aa bb
# touch "aa bb"
# ls
aa aa bb bb
# rm aa
rm:是否删除普通空文件 "aa"?y
# ls
aa bb bb
# rm bb
rm:是否删除普通空文件 "bb"?y
# ls
aa bb
# rm aa bb
rm: 无法删除"aa": 没有那个文件或目录
rm: 无法删除"bb": 没有那个文件或目录
# rm "aa bb"
rm:是否删除普通空文件 "aa bb"?y
# ls
# touch aa bb
# touch "aa bb"
# ls
aa aa bb bb
# ll
总用量 0
-rw-r--r--. 1 root root 0 10月 20 16:34 aa
-rw-r--r--. 1 root root 0 10月 20 16:34 aa bb
-rw-r--r--. 1 root root 0 10月 20 16:34 bb
------------------------------------------------------
# echo a b c
a b c
# echo "a b c"
a b c
------------------------------------------------------
# test=11
# echo "$test"
11
# echo '$test'
$test

# a=11
# b=22
# c=33
# echo "$a "
11
# echo '$a'
$a
# echo "$a $b $c"
11 22 33
# echo '$a $b $c'
$a $b $c
--------------------------------------------------
# date +%F
2018-10-20
# date +%Y%m%d
20181020
# date +%Y%m%d%H%M
201810201700
# rm -rf /root/test/*
# ls
# !tar
tar -zcf log.tar.gz /var/log
tar: 从成员名中删除开头的“/”
# ls
log.tar.gz
# tar -zcf log-`date +%F`.tar.gz /var/log
tar: 从成员名中删除开头的“/”
# ls
log-2018-10-20.tar.gz log.tar.gz
# tar -zcf log-`date +%Y%m%d%H%M`.tar.gz /var/log
tar: 从成员名中删除开头的“/”
# ls
log-201810201702.tar.gz log-2018-10-20.tar.gz log.tar.gz

反撇号或$()时,可以将命令执行的输出结果作为字符串存储,因此称为命令替换。
反撇号或$(),是命令的输出结果
反引号“引用命令”
双引号“整体”
单引号“整体,屏蔽特殊符号”

局部变量
全局变量
export 变量名=变量值

export xyz=456
[root@server0 ~]# echo $xyz
456
[root@server0 ~]# bash
[root@server0 ~]# echo $xyz
456


yyy=1
[root@server0 ~]# echo $yyy
1
[root@server0 ~]# bash
[root@server0 ~]# echo $yyy

[root@server0 ~]# exit
exit
[root@server0 ~]# echo $yyy
1


iii=222
export iii
[root@server0 ~]# bash
[root@server0 ~]# echo $iii
222
[root@server0 ~]# exit
exit
[root@server0 ~]# echo $iii
222

如果创建周期性任务,一定要记得加上时间,否则每一次备份都会覆盖之前的tar包,只保留最近一次
的备份。最好tar包名加上时间,这样就不怕覆盖了。如果每天都要备份2次,那么一定要记得加上时和分来创建!
---------------------------------------------------
# tar -zcf log-$(date +%Y%m%d%H%M).tar.gz /var/log
tar: 从成员名中删除开头的“/”
# ls
log-201810201702.tar.gz log-2018-10-20.tar.gz
log-201810201708.tar.gz log.tar.gz
----------------------------------------------------
vim /root/7.sh
cat /root/7.sh

#!/bin/bash

read -p "请输入用户名:" user
read -p "请输入密码:" pass
useradd $user
echo $pass |passwd --stdin $user

# chmod +x /root/7.sh
# /root/7.sh
请输入用户名:harry
请输入密码:123
更改用户 harry 的密码 。
passwd:所有的身份验证令牌已经成功更新。
---------------------------------------------------
终端显示控制

stty -echo
关闭终端输出(无显示)
stty echo
恢复终端输出(显示)
-----------------------------------------------------
read标准输入取值
read从键盘读入变量值完成赋值

格式:read [-p "提示信息"] 变量名
-p可选, -t可指定超时秒数

-------------------------------------------------------
# vim /root/7.sh
#!/bin/bash

read -p "请输入用户名:" user #注意,read提示符和变量之间要有空格
stty -echo #可以让下面用户输入时,密码不显示在屏幕上
read -p "请输入密码:" pass
stty echo #恢复显示屏幕输入的命令
useradd $user
echo $pass |passwd --stdin $user

# /root/7.sh
请输入用户名:xixi
请输入密码:更改用户 xixi 的密码 。
passwd:所有的身份验证令牌已经成功更新。

猜你喜欢

转载自www.cnblogs.com/summer2/p/10788017.html