BASH学习记录(一)
第十章 BASH
开机执行shell
1. vim /etc/rc.d/rc.local
2. 添加需要执行的脚本绝对路径 e.g /usr/local/virus/iptables/iptables.rule
-
Login Shell
登录时需要输入账户和密码才能取得的叫做
login shell
读取的系统配置文件
|--/etc/profile: 所有用户共享,系统整体配置 | |--/etc/profile.d/*.sh: 执行的sh命令 | |--/etc/locale.conf 语言设定 | |--/usr/share/bash-completion/completion tab补齐
读取的个人配置文件
~/.bash_profile (备选 ~/.bash_login, ~/.profile) bash依次查找上面三个配置,找到后就退出,所以只会加载一个配置文件
-
Non-login shell
不需要输入账户密码就能获取的shell叫做non-login Shell
- 登录X-window中启动的bash
- 登录bash后,再次调用bash启动子bash,不需要输入账户密码
语言调整
# 在/etc/locale.conf 中更改参数
# 插播:为什么在linux中的配置文件放在/etc下
# 答:/etc 来源于法语 et cetera, 表示and so on 等等的意思,用来放置一些乱起八糟的配置文件
快速编辑。
-
快速定位: 单词前后移动 esc + b/f , ctl + b/w ; 句子前后移动 ctrl + a, ctrl + end
-
快速删除: ctrl + u 删除左边, ctrl + k 删除右边, ctrl + w 删除1单词
-
第一个shell是由Steven Bourne开发的,所以就以他命名sh!
-
发行版中会预设很多shell 如/bin/sh, /bin/bash, /bin/tcsh, /bin/csh, linux中预设的是/bin/bash,兼容sh
-
查看登录后系统分配给用户的shell
[root@vm-centos7 ~]# cat /etc/passwd root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin ##: /sbin/nologin 就是默认给daemon分配的shell adm:x:3:4:adm:/var/adm:/sbin/nologin ......
-
bash特殊功能---为什么会预设
-
命令记忆功能,会当前会话完成后,会将该会话的命令记录到~/.bash_history中。
本次操作的命令历史是存储在内存中,退出登录后才会写到文件中,可以除错
-
命令取别名, e.g alias lm = 'ls -al', 后续输入lm则可以代替
-
job control: 将程序运行设置为 前台运行(foreground)或后台运行(background)
-
Shell Scripts & wildcard, 可以编写脚本程序,命令可以结合统配符,ls -l /usr/bin/X* --》查询X开头的文件
-
type
-
查看命令类型是否是内置命令
type [-tpa] name -t :查看命令类型 file-外部 alias-别名 builtin-内建 -p :若指令是外部指令时,会显示出完整文件名 e.g: type -p yum -a :从环境变量$PATH中,将所有的包含name的指令全列出来,包含alias
变量
-
打印变量
echo $变量名 或 echo ${变量} 若变量名不存在,则输出为空
-
声明变量
[root@vm-centos7 ~]# echo ${MYNAME} ##此时变量不存在,输出为空 [root@vm-centos7 ~]# MYNAME=yanglujian ##赋值变量 [root@vm-centos7 ~]# echo ${MYNAME} ##打印变量,有输出 yanglujian
-
追加变量
## 追加环境变量 PATH=${PATH}:/root/usr/.. #:为分隔符
-
指令嵌套
## 进入到内核目录中 ## uname -r 输出相应的内核版本信息,作为变量替换到cd命令中 cd /lib/modules/$(uname -r)/kernel ## 或 cd /lib/modules/`uname -r`/kernel
环境变量
-
系统变量 = 环境变量 + 自定义变量
-
常用环境变量
## env 查询环境变量 HOME: 家路径 SHELL: 当前的shell是哪个程序 HISTSIZE: 历史命令记录的笔数 MAIL:邮件信箱文件 PATH: 文件搜索路径 RANDOM: 随机数 /dev/random
-
env , set区别& export作用
evn: 显示的环境变量(全局变量), 在子bash中也可以获取到 set: 显示的系统变量(env变量 + 自定义变量) export: 让自变量变成evn变量, 输入export 自变量命令后,用env就能查看到自定义变量了
-
设置变量和删除变量
## 设置变量 变量名=值 ## 获取变量 ${变量名} ## 删除变量 unset 变量名
-
将环境变量变为自变量
# 将变量申明为环境变量 declare -x 变量名 # 将环境变量申明为自定义变量 declare +x 变量名
子shell
-
## 子shell,$()中的指令会开启子shell来执行,执行后的结果返回给挂起的父shell # uname -r 获取系统的内核版本信息 cd /lib/modules/$(uname -r)/kernel
-
子shell会继承父shell的环境变量,但是父shell获取不到子shell的环境变量
alias命令别名
-
查看所有别名
alias
-
取别名
alias lm='ls -al | more'
-
取消别名
unalias lm
history命令历史
- shell 会话期间历史记录是在内存中的,会话完成后记录到磁盘中~/.bash_history
数据流重导向
< 符号表示标准输入流 stardard input
<< 定义结束符 如 “eof”. 标准输入遇到eof字符就截止
> 或 1> 符号表示标准输出流 stardard output
2> 符号表示标准错误输出流
2>> 标准错误追加
>>符号表示 标准输入流定义结束字符, e.g "eof" 不用ctrl + d
&> (标准输出 + 标准错误输出) 都重导向
-
cat命令: 将标准输入 或文件 , 输出到 标准输出
cat > catfile << "eof" ## 解释: 【> catfile】表示将catfile作为标准输出
-
将标准输出> 重定向到标准错误输出
1>&2 ## 必须写在命令行最后 应用: 将命令的错误输出和正常输出 都重定向到一个文件 例子: find /home -name .bashrc >log.txt 2>&1 该命令会产生标准输出流和标准错误输出流, 都重定向到log.txt文件中
-
理解stdout,stdin,std error out
标准输入流 --> command命令 --> 标准输出流(命令正常执行,输出处理后的数据) |--> 标准错误输出流(命令异常退出,输出异常信息)
-
黑洞地址
/dev/null 所有的输出流重定向到该地址将不会有副作用。 应用: 命令执行后,不输出 例子: cat fileName > /dev/null
-
命令组合
command1 || command2 : 命令1执行成功后就不执行命令2,命令1不成功才会执行命令2 command1 && command2 : 命令1执行成功后才会执行命令2,否则不执行
-
双向重定向 tee 将标准输入流分叉,在原先的标准输出流的基础上,拷贝出文件输出流
标准输入流 --> tee命令 ---> 标准输出流stdout |__ 文件输出流
管道命令 |
-
前一个命令的标准输出 作为 后面命令的标准输入。
-
不是每个命令支持管道
-
[stdin -->command1-->stdout] --> [stdin -->command2-->stdout]
-
linux命令分为支持管道命令和不支持管道命令
- 支持管道的命令 在使用时不需要额外操作,管道右边的命令自动会将左端
断行符
- linux断行符和Dos断行符不一样,linux( \n)
^M$
, DOS(\r\n)$(LF)
文本操作
- cut 截取
- grep 正则查找
- sort 排序, wc 字符计数
- Tee 双重定向
- tr 字符串修剪trim
- split 大文件分成小文件
- xargs 将文本分析后作为参数,给命令
Shell Script
- centos6.x之前,执行/etc/init.d/*目录下所有脚本运行 --> centos7, systemd命令取代之前的形式
- 开机启动程序 --> /etc/rc.d/rc.local 目录 (rc--run command, .d -- directory)
- 重启系统日志记录文件,也是运行shell script (/etc/init.d/rsyslogd restart)
- 开启定时任务分析系统日志信息,若出现特定异常,封IP等操作, 常用作服务器的运维管理,不做大量的计算使用
执行
-
sh shell.sh
解释: /bin/是${PATH}环境变量,且/bin/sh 是/bin/bash的link,shell.sh只需要r权限 -
~/bin
是会自动注册到环境变量中的,所以可以将自定义的shell文件放到该目录下,执行时候直接用 -
使用./shell.sh的原因。 ./不在环境变量中, 此时shell.sh 需要 rx权限
-
以上是直接下达指令,都是开启子bash来执行,执行完回到父bash,类似方法调用
需要注意的是:子bash中创建的自定义变量,在父bash中无法获取,类似方法栈中的变量都是隔离的
-
使用source(或者. ) 执行shell脚本 ,是在父bash中运行
编写模板
-
!/bin/bash 告诉当前bash使用哪个sh来执行这个shell脚本,这行若不配置,系统就不知道用什么shell来执行这份脚本
-
PATH=... export PATH ,将所需变量声明为环境变量,在bash执行过程中经常会启动子bash来执行指令,
子bash会继承父bash的环境变量,而子bash的环境变量父bash是不可视的,这里自定义PATH,且将PATH export
为环境变量的作用是让脚本运行过程中,不必去指定指令的绝对路径
-
Exit 0 表示bash正常结束 1表示异常-------》exit 数字,后续使用 echo $? 可以查看上次脚本退出时候的状态
#!/bin/bash
# Program:
# 功能介绍
# History:
# 编辑历史
# 2020/07/10 ylj 版本信息
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
echo -e "Hello World~ \a \n"
exit 0
变量
# ./shell.sh 或 sh shell.sh 执行的脚本都是在子bash中进行,父shell挂起(source shell.sh不是)
# 在sh文件中申明的变量存在于子bash中,父bash无法获取到子bash中的变量,需要export才可以获取
# 变量打印 echo ${变量名}, e.g echo ${MAIL}
# 变量设置 变量名="值", e.g username="yanglujian"
# 查看环境变量 env 获取 export
# 查看全部变量(环境 + 自定义): set
# 取消删除变量 unset 变量名
环境变量
-
环境变量初始化,bash初始化时会读取bash配置文件(1.系统配置 2.自定义配置)
当系统结束时,运行中的设置的变量都会无效,需要做持久化才能在下一次进入系统
时,变量依旧能读取
-
shell开启时的设定变量,如 HOME, MAIL, PATH etc... 默认设定的环境变量用大写,以区别自定义变量
-
全局变量,在当前bash和子bash中都有效
-
变量名全大写,表示是系统内设的变量
-
## 查看环境变量 方式1 env ## 查看环境变量 方式2 export
自定义变量
- 局部变量,只在当前的bash会话中有效,对子bash不可视
- 变量名小写即可,便于区分
创建变量
# 创建变量--值从键盘输入获取 read, 等待30秒输入后将值存入var
read -p "请输入值:" -t 30 var
# 创建变量--同时声明变量类型,declare [-aixr] var,变量默认是字符串类型
# -a array, -i integer, -x export(声明为环境变量), -r readonly(只读,也无法被unset)
#
declare -i sum=100+200+300
declare -a arr
arr[0]="num1"
arr[1]="num2"
arr[2]="num3"
变量内容修剪
# 目标字符串: str="/内容0:/内容1:/内容2:/内容3"
# 删除 【/内容0:】, # 表示从左到右 最短匹配,删除
echo "${str#/*:}" --> /内容1:/内容2:/内容3
# 删除 【/内容0:/内容1:/内容2:】 ## 表示从左到右 最长匹配,删除
echo "${str##/*:}" --> /内容3
# 删除 【:/内容3】 % 表示从右到左 最短匹配,删除
echo "${str%:/*}" --> /内容0:/内容1:/内容2
# 删除 【:/内容1:/内容2:/内容3】 %% 表示从右到左 最长匹配,删除
echo "${str%%:/*}"--> /内容0
变量内容默认值处理(条件替换)
## 当变量不存在时,则返回缺省值. 当username不存在时候,用yanglujian来显示, -号有临时表示的意思
echo ${username-yanglujian} -----减号表示设定值是在 变量没有赋值时起作用
## 当变量不存在或者是空时候,则返回缺省值。当变量为username不存在或值为空时,返回yanglujian
echo ${username:-yanglujian}
## 当变量不存在时,则返回空值,当变量存在时候(空值+非空值),加工为设定值。 +号有临时表示的意思
echo ${usename+yanglujian} ----加号表示设定值是在 变量有赋值的情况下起作用,:冒号是空值的处理
## 当变量不存在或为空时,则返回空值,当变量存在时候(非空值),加工为设定值。
echo ${username:+yanglujian}
## 当变量不存在时,赋值为默认值返回。有值时返回该值(包括空值和非空值)。 =等号有赋值的意义
echo ${username=yanglujian}
## 当变量没有值或为空值时候,赋值为默认值返回
echo ${username:=yanglujian}
## 当变量不存在时,输出到stderr,否则输出值(变量有值或为空值)。当username不存在时,标准错误流输出值不存在。 ?问号有报警的意思
echo ${username?值不存在}
## 当变量不存在或为空时候,则输出到stderr,否则输出值(变量有非空值),当username不存在或值为空时,标准错误输出流输出 值不存在或为空
echo ${username:?值不存在或为空}
判断
文件,字符串判断
条件判断[ ], 变量用双引号括起来
- [ ${变量} == ]
- 查看变量是否为空 [ -z "${HOME}" ] 0空 1非空
循环
各种括号的作用
- 小括号(), 小括号中的命令会开启子shell来执行!!