bash特性
bash特性一:命令历史:
shell进程会在其会话中保存此前用户提交执行过的命令:
history
定制history
的功能,可通过命令历史相关环境变量实现:
- HISTSIZE:命令历史记录的条数
- HISTFILE:指定历史文件,默认为~/.bash_history
- HISTFILESIZE:命令历史文件记录历史的条数
history命令用法:
history [-c] [-d offset] [n] history -anrw [filename] history -ps arg [arg...] -c: 清空命令历史 -d offset: 删除历史中指定的第offset个命令 n: 显示最近的n条历史 -a: 追加本次会话新执行的命令历史列表至历史文件 -r: 读历史文件附加到历史列表 -w: 保存历史列表到指定的历史文件 -n: 读历史文件中未读过的行到历史列表 -p: 展开历史参数成多行,但不存在历史列表中 -s: 展开历史参数成一行,附加在历史列表后 !!:执行上一条命令 string 重复前一个以“string”开头的命令 !?string 重复前一个包含string的命令 !string:p 仅打印命令历史,而不执行 !$:p 打印输出 !$ (上一条命令的最后一个参数)的内容 !*:p 打印输出 !*(上一条命令的所有参数)的内容 ^string 删除上一条命令中的第一个string ^string1^string2 将上一条命令中的第一个string1替换为string2 !:gs/string1/string2 将上一条命令中所有的string1都替换为 string2 使用up(向上)和down(向下)键来上下浏览从前输入的命令 ctrl-r来在命令历史中搜索命令 (reverse-i-search)`’: Ctrl+g:从历史搜索模式退出 要重新调用前一个命令中最后一个参数: !$ 表示 Esc, .(点击Esc键后松开,然后点击 . 键) Alt+ .(按住Alt键的同时点击 . 键)
控制命令历史的记录方式:
环境变量:HISTCONTROL
- ignoredups 默认,忽略重复的命令,连续且相同为“重复”
- ignorespace 忽略所有以空白开头的命令
- ignoreboth 相当于ignoredups, ignorespace的组合
- export 变量名="值“
- 存放在 /etc/profile 或 ~/.bash_profile
bash特性二:tab补全功能:
命令补全:
1)查找内部命令;
2)查找外部命令:bash根据PATH环境变量定义的路径,自左而右在每个路径搜寻以给定命令名命名的文件;
第一次找到的命令即为要执行的命令,用户给定的字符串只有一条惟一对应的命令,直接补全,否则,再次Tab会给出列表。
[root@centos7~]#echo $PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin 目前以后的PATH变量路径 [root@centos7~]#wh 输入wh后按tab键,如果唯一就会补全,不唯一再按tab键就会显示多个命令 whatis whereis which while whiptail who whoami
bash特性三:命令行展开:
- ~:自动展开为用户的家目录,或指定的用户的家目录;
- 可承载一个以,分隔的路径列表,并将其进行展开为多个路径。
[root@centos7data]#mkdir -p test{1,2}/{a,b{x,y}} [root@centos7data]#tree . ├── test1 │ ├── a │ ├── bx │ └── by └── test2 ├── a ├── bx └── by 通过tree能够展示当前data目录下有多少个子目录。
bash特性四:历史命令执行的结果状态
bash通过状态返回值来输出此结果:
成功:0
失败:1-255
命令执行完成之后,其状态返回值保存于bash的特殊变量$?中;
命令正常执行及其功能不同,结果各不相同;
引用命令的执行结果:
$(command),如:mkdir $(date +%H-%M-%S),即引用date运行结果来执行命令,即创建date运行结果得到的数值的文件夹
'command'
[root@centos7data]#date 当命令执行正确时 Sun Oct 27 21:01:14 CST 2019 [root@centos7data]#echo $? 0 echo $?就会显示0,默认命令执行状态正确
[root@centos7data]#date -sss 当命令输入错误时 date: invalid date ‘ss’ [root@centos7data]#echo $? 1 echo $? 执行结果就是1,表示当前命令执行状态错误
bash特性五:引用:
- 强引用:' '
- 弱引用:" "
- 命令引用:` `;不建议使用:尽量使用$(cmd)
[root@centos7~]#echo "$PATH" 弱引用,可以识别到里边的命令变量 /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin [root@centos7~]#echo '$PATH' 强引用就会将里边的命令当初字符串进行打印 $PATH [root@centos7~]#echo `echo $PATH` 反向单引号,引用命令,因此需要echo $PATH完整的命令才行,才会进行正确打印 /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
bash特性六:快捷键
- Ctrl + l 清屏,相当于clear命令
- Ctrl + s 阻止屏幕输出,锁定
- Ctrl + q 允许屏幕输出
- Ctrl + c 终止命令
- Ctrl + z 挂起命令
- Ctrl + a 光标移到命令行首,相当于Home
- Ctrl + e 光标移到命令行尾,相当于End
- Ctrl + u 从光标处删除至命令行首
- Ctrl + k 从光标处删除至命令行尾
- Alt + r 删除当前整行
注意:Alt组合快捷键经常和其它软件冲突
bash特性七:别名
显示当前shell进程所有可用的命令别名:alias
定义别名NAME,其相当于执行命令VALUE:
- alias NAME='VALUE'
在命令行中定义的别名,仅对当前shell进程有效;
如果想永久有效,要定义在配置文件中
仅对当前用户:~/.bashrc
对所有用户有效:/etc/bashrc
bash特性八:通配符
* 匹配零个或多个字符 ? 匹配任何单个字符 ~ 当前用户家目录 ~mage 用户mage家目录 ~+ 当前工作目录 ~- 前一个工作目录
[0-9] 匹配数字范围 [a-z]:小写字母 [A-Z]:大写字母 [wang] 匹配列表中的任何的一个字符 [^wang] 匹配列表中的所有字符以外的字符
预定义的字符类:man 7 glob
[[:upper:]]匹配任意大写字母 [[:lower:]]匹配任意小写字母 [[:alpha:]]匹配所有字母 [[:digit:]]匹配所有数字 [[:alnum:]]匹配所有的字母和数字 [[:space:]]匹配所有空白字符 [[:punct:]]匹配所有标点符号
[^]:匹配指定范围外的任意单个字符:
[^[:upper:]]除大写字母以外任意字符
[^[:lower:]]除小写字母以外任意字符
[^[:alpha:]]除字母以外任意字符
[^[:digit:]]除数字以外任意字符,或者[^0-9]
[^[]:alnum:]除字母和数字以外的任意字符(即符号)
[^[:space:]]匹配所有空白字符
[root@centos7data]#ls [^[:digit:]]*[0-9] -d 显示以非数字开头以数字结尾的文件 test1 test2
bash特性九:标准I/O和管道
标准输入和输出
程序:指令+数据
读入数据:Input
输出数据:Output
打开的文件都有一个fd: file descriptor (文件描述符)
Linux给程序提供三种I/O设备
标准输入(STDIN)-0 默认接受来自键盘的输入
标准输出(STDOUT)-1 默认输出到终端窗口
标准错误(STDERR)-2 默认输出到终端窗口
I/O重定向:改变默认位置
IO重定向:
STDOUT和STDERR可以被重定向到文件
命令 操作符号 文件名
支持的操作符号包括:
1)> 把STDOUT重定向到文件
2)2> 把STDERR重定向到文件
3)&> 把所有输出重定向到文件
> 文件内容会被覆盖
[root@centos7data]#echo 22 > f1
[root@centos7data]#cat f1
22
set –C 禁止将内容覆盖已有文件,但可追加
>| file 强制覆盖
[root@centos7data]#echo aa >| f1
[root@centos7data]#cat f1
aa
set +C 允许覆盖
>> 原有内容基础上,追加内容
输出流重定向:>>
追加输出:
[root@centos7data]#cat f1 aa [root@centos7data]#ls /data/ >> f1 [root@centos7data]#cat f1 aa f1 scripts
错误输出流重定向:
[root@centos7data]#cat f11 2> f2 错误输出
[root@centos7data]#cat f22 2>> f2 错误追加
[root@centos7data]#cat f2
cat: f11: No such file or directory
cat: f22: No such file or directory
合并标准、错误输出流:
[root@centos7data]#ls /boot /dir &> f2 第一种写法对的错的放一起
[root@centos7data]#cat f2
ls: cannot access /dir: No such file or directory
/boot:
config-3.10.0-957.el7.x86_64
[root@centos7data]#ls /boot /dir > f2 2>&1 正确的的放入f2,标准错误放入正确里
[root@centos7data]#cat f2
ls: cannot access /dir: No such file or directory
/boot:
config-3.10.0-957.el7.x86_64
[root@centos7data]#ls /boot /dir 2>&1 > f2 错误的放入标准输出,此时已经打印在屏幕里,然后才把正确的放进f2 此写法错误
ls: cannot access /dir: No such file or directory
[root@centos7data]#cat f2
/boot:
config-3.10.0-957.el7.x86_64
[root@centos7data]#ls /boot /dir 2> f2 1>&2 错误的放进f2里,正确的放入错误里
[root@centos7data]#cat f2
ls: cannot access /dir: No such file or directory
/boot:
config-3.10.0-957.el7.x86_64
输入重定向:<
[root@centos7data]#cat > f1 2*3 2^3 ^C [root@centos7data]#bc <f1 6 8 [root@centos7data]#bc <f1 > f2 将f1文件内容传到bc然后再传给f2 [root@centos7data]#cat f2 6 8
[root@centos7data]#cat < f1 2*3 2^3 [root@centos7data]#cat < f1 >f3 将f1显示的内容再传给f3 [root@centos7data]#cat f3 2*3 2^3
tr命令
tr 转换和删除字符
tr [OPTION]... SET1 [SET2]
选项:
-c --complement:取字符集的补集 -d --delete:删除所有属于第一字符集的字符 -s --squeeze-repeats:把连续重复的字符以单独一个字符表示 -t --truncate-set1:将第一个字符集对应字符转化为第二字符集对应的字符 [:alnum:]:字母和数字 [:alpha:]:字母 [:cntrl:]:控制(非打印)字符 [:digit:]:数字 [:graph:]:图形字符 [:lower:]:小写字母 [:print:]:可打印字符 [:punct:]:标点符号 [:space:]:空白字符 [:upper:]:大写字母 [:xdigit:]:十六进制字符
示例:
[root@centos7data]#tr 'a-z' 'A-Z' < /etc/issue > f2 将/etc/issue的配置文件转换为大写 [root@centos7data]#cat f2 \S KERNEL \R ON AN \M
多行重定向:
[root@centos7data]#cat > f1 <<EOF 将内容多行重定向 > aaa > ddd > ccc > sss > EOF 最后以EOF结束 [root@centos7data]#cat f1 aaa ddd ccc sss
[root@centos7data]#cat > f1 << EOF > My hostname is `hostname` > My username is `uname -r` > EOF [root@centos7data]#cat f1 My hostname is centos7.localdomain My username is 3.10.0-957.el7.x86_64
[root@centos7data]#mail -s "1st mail" root << EOF > hello > who are you > your name > EOF [root@centos7data]#mail Heirloom Mail version 12.5 7/5/10. Type ? for help. "/var/spool/mail/root": 1 message 1 new >N 1 root Sun Nov 3 21:48 20/617 "1st mail" & 1 Message 1: From root@centos7.localdomain Sun Nov 3 21:48:04 2019 Return-Path: <root@centos7.localdomain> X-Original-To: root Delivered-To: root@centos7.localdomain Date: Sun, 03 Nov 2019 21:48:04 +0800 To: root@centos7.localdomain Subject: 1st mail User-Agent: Heirloom mailx 12.5 7/5/10 Content-Type: text/plain; charset=us-ascii From: root@centos7.localdomain (root) Status: R hello who are you your name & quit Held 1 message in /var/spool/mail/root
管道:
[root@centos7data]#whoami | tr 'a-z' 'A-Z' ROOT [root@centos7data]#echo {1..100} |tr ' ' '+'|bc 5050 [root@centos7data]#ls /data /error 2>&1 | tr 'a-z' 'A-Z' 对的错的全部导入,并转换为大写字母 LS: CANNOT ACCESS /ERROR: NO SUCH FILE OR DIRECTORY /DATA: [A-Z] BC F1 F2 F3 SCRIPTS TR [root@centos7data]#ls /data /error |& tr 'a-z' 'A-Z' 这种写法慎重 LS: CANNOT ACCESS /ERROR: NO SUCH FILE OR DIRECTORY /DATA: 1 2 [A-Z] BC F1 F2 F3 SCRIPTS TR
less :一页一页地查看输入
ls -l /etc | less
mail: 通过电子邮件发送输入
-b<地址>:指定密件副本的收信人地址; -c<地址>:指定副本的收信人地址; -f<邮件文件>:读取指定邮件文件中的邮件; -i:不显示终端发出的信息; -I:使用互动模式; -n:程序使用时,不使用mail.rc文件中的设置; -N:阅读邮件时,不显示邮件的标题; -s<邮件主题>:指定邮件的主题; -u<用户帐号>:读取指定用户的邮件; -v:执行时,显示详细的信息。
echo "test email" | mail -s "test" wang
echo输入的命令,-s
表示邮件的主题,后面的admin@linuxde.net
则是邮件的接收人,输入完这行命令后回车,会进入邮件正文的编写,我们可以输入任何文字,比如上面的两行。当邮件正文输入完成后,需要按CTRL+D结束输入,此时会提示你输入Cc地址,即邮件抄送地址,没有直接回车就完成了邮件的发送。
echo "hello,this is the content of mail.welcome to www.linuxde.net" | mail -s "Hello from linuxde.net by pipe" admin@linuxde.net
管道中 - 符号
示例:
将 /home 里面的文件打包,但打包的数据不是记录到文件,而是传送到 stdout,
经过管道后,将 tar -cvf - /home 传送给后面的 tar -xvf - , 后面的这个 - 则是取
前一个命令的 stdout, 因此,就不需要使用临时file了
tar -cvf - /home | tar -xvf - 前面的-和后面的-文件名一致
重定向到多个目标(tee)
命令1 | tee [-a ] 文件名 | 命令2
既将命令的打印结果显示出来,又保存到当前的文件中
-a 追加
使用:
1)保存不同阶段的输出
2)复杂管道的故障排除
3)同时查看和记录输出
[root@centos7data]#uname -r | tee /data/log 将显示的内容在屏幕上显示并保存到log文件中 3.10.0-957.el7.x86_64 [root@centos7data]#cat log 3.10.0-957.el7.x86_64
小练习:处理字符串“xt.,l 1 jr#!$mn 2 c*/fe 3 uz 4”,只保留其中的数字和空格
[root@centos7data]#echo 'xt.,l 1 jr#!$mn 2 c*/fe 3 uz 4' | tr -dc '[0-9 ]' 前面内容有!#,需要用单引号引起来,才能识别里边的内容 1 2 3 4