bash的基础特性之
globbing:文件名通配【一次操作多文件】
匹配模式:元字符
*:匹配任意长度的任意字符【pa* 已pa开头的任意文件 ls pa*,但是在/目录下ls好像显示有问题】
?:匹配任意单个字符【如果是 pa?必须是pa后加上一个字符】
[]:匹配指定范围内的任意单个字符
[a-z],[a-z0-9]
[[:upper:]]匹配所有大写字母
[[:lower:]]:匹配所有 小写字母
[[:alpha:]]:匹配所有字母
[[:digit:]]:匹配所有数字
[[:alnum:]]:匹配所有字母和数字
[[:space:]]:匹配所有空白字符
[[:punct:]]:匹配所有标点符号
[^]:匹配指定范围外的任意单个字符
[^[:upper:]]
[^0-9]
[^[:alnum:]]
举例:复制/home/myhome下所有以m开头非数字结尾的文件夹到目标地址:cp /home/myhome/m*[^0-9] /to/myPath
IO重定向及管理
程序:指令+数据
程序也有数据的IO
可用于输入的设备:文件
键盘设备、文件系统上的常规文件、网卡等;
可用于输出的设备:文件
显示器、文件系统上的常规文件、网卡灯。
程序的数据流有三种:
输入的数据流:<--标准输入(stdin),一般是键盘;
输出的数据流:-->标准输出(sdtout),一般是显示器;
错误的输出流: -->错误输出(stderr),一般也是显示器。
fd:file descriptor 文件描述符
标准输入:0
标准输出:1
错误输出:2
特殊设备:/dev/null[这个还是不是很理解,但是看到老师有写,在创建用户时:
id user1 &> /dev/null || useradd user1
]
IO重定向:
输出重定向:>
可以输出到其他文件中,例如cat ./m.txt > ./n/i.txt此时看./n/i.txt的文件就是之前./m.txt的内容了,也可以输出到其他终端上,例如cat ./m.txt > /dev/tty1此时登录tty1就能够看到这个消息
特性:覆盖输出
追加输出重定向:>>保留原有文件内容追加,例如cat m.txt >> n.txt 会把m和n的文件合并到n文件
set -C
禁止覆盖输出重定向文件
此时可以使用强制覆盖输出:>|
set +C
关闭上述特性
set -/+ C仅对当前shell有效
错误输出重定向:2> ,2>>
这个是把命令执行的错误信息输出,而不是正常数据的输出
合并正常输出流和错误输出流:
1、&>,&>>
2、command > /path/to/file 2>&1
command >> /path/to/file 2>&1
相应的信息输出到file,如果报错也追加输入
输入重定向:
<
tr命令:把输入的数据当中的字符,反思在SET1定义范围内出现的,对位转换为SET2中字符,如果使用参数-d,且SET2为空则将SET1中的字符进行删除显示并不删除源数据。
tr [a-z] [A-Z] < /path/to/file
会把file文件中的字符转换为大写显示,但是源文件依然不变。
<<:here documents
交互式:cat << EOF 结束后输入EOF即会显示交互的内容
输出至文件:cat > /path/to/file << EOF 结束后输入EOF无反应,交互内容保存至file中
管道
连接程序,实现将前一个命令的输出直接重定向为后一个程序的输入 COMMAND1 | COMMAND2 | COMMAND3
例如:cat m.txt | tr 'a-z' 'A-Z'则会将把m.txt文件中的小写字母替换为大写
who | head -2 查看前两个用户
tee命令 把数据流分为两叉,既干这个又干那个
例如:cat m.txt | tee /etc/m.tee | tr 'a-z' 'A-Z' 既会把m.txt的数据通过tr命令显示小写替换为大写,还能把m.txt的数据复制给/etc/m.tee文件
bash基础特性之自动补充命令
命令补全:
shell程序接收到用户执行命令的请求,分析完成后,最左侧的字符串会当作命令。
命令的查找机制:
查找内部命令;
根据PATH环境变量中设定的目录,自作而又诸葛搜索目录下的文件名。
如果给定的打头字符串能够唯一标识某一命令程序文件,则自动补全,如果不能唯一识别,再按一次tab,显示出所有以此字符串打头的列表。
路径补全:
根据给定的起始路径补全。
如果给定的打头字符串能够唯一标识某一路径文件,则自动补全,如果不能唯一识别,再按一次tab,显示出所有以此字符串打头的列表。
bash的基础特性之命令行展开
~:自动展开为用户的家目录,或指定的用户的家目录;
{}:可承载一个以逗号分隔的路径列表,并能够将其展开为多个路径。
例如/tmp/{a,b} 相当于/tmp/a /tmp/b
mkdir {a,b}_{c,d} 会 创建a_c,a_d,b_c,b_d
bash基础特性之命令执行的状态结果
命令执行的状态结果:
bash通过装填返回值来输出此结果:
成功:0;
失败:1-255.
保存于环境变量$?中
命令执行完成后,有的还会有命令返回值,根据命令及其功能不同,结果各不同。
引用命令的执行结果:
$(command)或`command`
例如mkdir $(date %m-%d-%y)
bash基础特性之快捷键
ctrl + a 跳转至命令行行首
ctrl + e 跳转至命令行行尾
ctrl + u 删除行首至光标所在之处之间的所有字符;
ctrl + k 删除光标所在处至行尾的所有字符
ctrl + l clear清屏
bash特性及bash脚本编程初步
终端:附着在终端的接口 程序:
GUI:KDE,GNome,Xfce
CLI:/etc/shells
bash的特性:
命令行展开:~,{}【这个知识点有点忘了,需要重新去温习一下2020/03/22】
命令别名:alias,unalias
命令历史:history
文件名通配:glob
快捷键:Ctrl +a,e,u,k,l
命令补全:通过$PATH查找
路径补全:通过打头位置查找
命令hash:缓存此前运行的命令的程序位置(key:value数据结构,key搜索键,value值)
-d 删除hash表中的某个命令历史【使用场景,例如把cat程序从目录A移动到了目录B,但是hash表中的缓存依然是目录A,那么则会执行出错,此时删除一下hash表中的cat命令即可,如果在hash表中没有记录,则会去环境变量中查找此命令的实际位置】
-r 清空hash表所有的记录
变量:指向内存空间【修改数据只能在内存中操作】
程序:指令+数据
指令:由程序文件提供;
数据:通过IO设备获取、通过文件获取、通过管道、通过变量
程序也可称为:算法+数据结构
变量名:指向内存中某一段空间的起始地址
变量赋值:name = value【shell中】
变量类型:决定了存储格式、表示数据范围、参与的运算
编程语言:
强类型变量:c
弱类型变量:
bash把所有变量通通视为字符型,做四则运算时会自动转换为数值型;
bash中的变量无需事先声明,声明和赋值过程同时实现;声明:类型、变量名;
变量替换:把变量名出现的位置替换为其所指向的内存空间中的数据;【有点不太理解】
变量引用:${var_name},$var_name,当变量在一个字符串内部,大括号不可省略,例如"Hi ,${name}"
变量名:数字、字母、下划线,不能以数字开头;见名知义,命名机制遵循某种法则,且不能使用程序的保留字,例如if,else,then,while等
bash的变量类型:
本地变量:作用域仅为当前shell【不包括子进程】
赋值:name = value
引用:${name},$name
""显示变量名
''显示变量值
查看变量:set命令
变量撤销:unset name【此处非变量引用,不使用$】
环境变量:作用域为当前shell进程及子进程【例如在shell中运行bash实际上进入了子进程shell,运行exit退出shell子进程,对父进程无效】,退出之后则失效
变量赋值:
1、export name = value
2、name = value
export name
3、declare -x name = value
4、name = value
declare -x name
变量引用${name},$name
注意:bash内嵌了许多环境变量(通常为全大写字符),用于定义bash的工作环境,例如:PATH,HISTFILE,HISTFILESIZE,HISTCONTROL,SHELL,HOME,UID,PWD<OLDPWD
查看环境变量的命令:export ,declare -x,printenv,env
撤销环境变量:unset name
只读变量:
declare -r name
readonly name
只读变量无法重新赋值,且不支持撤销,存活时间为当前shell进程的生命周期,随shell进程终止而终止
局部变量:作用域仅为某代码片段(函数上下文)
位置参数变量变量:当执行脚本的shell进程传递的参数;
特殊变量:shell内置的特殊功用的变量;
例如:$?【其中一个特殊变量】上一个命令执行状态的结果0表示成功,10255表示失败。
多命令执行:
command1,command2,command3,...执行顺序为1-2-3-...
逻辑运算:
运算数:真(true,yes,on,1)
假(false,no,off,0)
与:&
或:||
非:!
#异或:XOR
短路法则:
COMMAND1 && COMMAND2 命令1失败命令2不执行,命令1成功命令2执行;
COMMAND1 ||COMMAND2 命令1失败命令2执行,命令1成功命令2不执行;
示例:id $username || useradd $username(查看此用户信息,如果不存在则进行创建用户)
shell脚本编程:
编程语言的分类:根据运行方式
编译运行:源代码 --> 编译器(编译)--> 程序文件;
C语言
解释运行:源代码-->运行时启动解释器,有解释器边解释边运行;
根据其编程过程中功能的实现是调用库还是调用外部的程序文件:
shell脚本编程:利用系统上的命令及编程组件进行编程;
完整编程:利用库或编程组件进行编程。
编程模型:过程式编程语言,面向对象的编程语言
程序 = 指令 + 数据
过程式:以指令为中心来组织代码,数据是服务于代码;
顺序执行、选择执行,循环执行
代表:C,bash
对象式:以数据为中心来组织代码,围绕数据来组织指令;
类(class):实例化对象;
代表:java,python,c++
shell脚本编程特性:过程式编程,解释运行,依赖于外部程序文件运行。
格式/如何写:
脚本文件第一行顶格,给出shebang【解释器路径】用于指明解释执行当前脚本的解释器文件。
常见的解释器:
#!/bin/bash
#!/usr/bin/python
#!/usr/bin/perl
文本编辑器:
行编辑器:sed
全屏幕编辑器:nano,vi,vim
shell脚本是什么:
命令的堆积;
但很多命令不具有冥等性,所以需要程序逻辑来判断运行条件是否满足,以避免其运行中发生错误
运行脚本:
1、赋予执行权限,并直接运行此程序
chmod +x /path/to/file
2、直接运行解释器,将脚本以命令行参数传递给解释器程序(无需增加执行权限);
bash /path/to/file
注意:脚本中,除了shebang,余下所有以#开头的行和空白行都会被视作注释行而忽略,此即为注释行;shell脚本的运行是通过运行一个子shell进程实现的。
引申:为什么有些sh文件无法直接运行: 1、没有添加x权限,或当前用户不具备权限;2、需要添加地址,因为默认系统会去环境变量找此命令,但是可能不存在与环境变量目录下。
bash的配置文件
两类:
profile类:为交互式登录shell进程提供配置
全局:对所有用户都生效;
/etc/profile
/etc/profile.d/*.sh
用户个人:仅对当前用户有效;
~/.bash_profile
功用:
1、用户定义环境变量;
2、运行命令或脚本
bashrc类:为非交互式登录的shell进程提供配置
全局:
/etc/bashrc
用户个人:
~/.bashrc
功用:
1、定义本地变量;
2、定义命令别名。
仅管理员可以修改全局配置文件。
登录类型:
交互式登录shell进程:
直接通过某终端输入账号密码登录打开的shell进程;
使用su - username 或su -l username执行的登录账号切换;
非交互式登录shell进程:
使用su usename执行的登录切换【这里没有-】;
图形界面下打开的终端;
运行脚本。
交互式登录shell进程配置文件读取次序:
/etc/profile -- >/etc/profile.d/* -->~/.bash_profile --> ~/.bashrc --> /etc/bashrc
非交互式登录shell进程配置文件读取次序:
~/.bashrc --> /etc/bashrc --> /etc/profile.d/*
命令行中定义的特性,例如变量和别名作用域为当前shell进程的生命周期;
配置文件定义的特性,只对随后新启动的shell进程有效;
如果想通过配置文件定义的特性立即生效:
1、通过命令行重复定义一次;
2、让shell进程重读配置文件:
source /path/to/conf_file
或 . /path/to/conf_file【这里的.即为source命令】
实践验证,在profile文件中环境变量修改之后,source一下,发现当前session的环境变量还在,并且把新的这个环境变量增加上了。
巧用:如果想让每个登录用户登陆时都能够看到一行提示信息,可以在/etc/profile.d/目录 下新建一个例如welcom.sh的文件,写下echo “你想让每个登录用户看到的信息”