bash 中符号作用
重定向
输入输出重定向、以及 wc 命令
标准输入输出设备
设备 | 设备文件名 | 文件描述符 | 类型 |
---|---|---|---|
键盘 | /dev/stdin | 0 | 标准输入 |
显示器 | /dev/stdout | 1 | 标准正确输出 |
显示器 | /dev/stderr | 2 | 标准错误输出 |
说明 —— Linux 中一切皆文件,所有设备都以文件的方式表示
- 块设备文件 —— 存储数据
- /dev/sr0 —— 光盘(企业级超级光盘:1.6 PB 的存储空间,光盘相比硬盘更能长时间保存)
- /dev/sda —— 第一块硬盘
- 字符设备 —— 传输数据,输入输出
- /dev/stdin —— 键盘
- /dev/stdout —— 显示器,标准正确输出,正确结果
- /dev/stderr —— 显示器,标准错误输出,错误结果
- 特殊设备
- /dev/null —— 黑洞
注:标准输出,指输出到显示器
可以通过重定向符号将输出结果输出到其它位置 —— 输出重定向,输出到文件
bash 的输出重定向 —— 重定向符号(一般写法)
- > —— 正确结果覆盖,等同于 1>
- >> —— 正确结果追加,等同于 1>>
- 2> —— 错误结果覆盖
- 2>> —— 错误结果追加
- &> —— 正确和错误的结果都重定向覆盖
- &>> —— 正确和错误的结果都重定向追加
例1:标准输出
- echo “hello world” —— /dev/stdout,标准正确输出,输出到显示器,输出到当前窗口
- lllllll --》未找到命令 —— /dev/stderr,标准错误输出,同样输出到显示器,当前窗口
例2:重定向输出
- echo “hello world” > /dev/null —— 重定向输出,输出到 /dev/null,黑洞,特殊设备
- echo “hello world” >> a.txt —— 重定向输出,输出到文件
重定向输出:将显示到屏幕上的内容写入指定文件
例3:使用 cat 配合重定向合并文件内容
- cat a.txt b.txt > c.txt
例4:正确输出和错误输出同时保存 —— 分别保存
- 命令 1>> 文件1 2>> 文件2 —— 把正确的输出追加到文件1 中,把错误的输出追加到文件2 中
注:“>” 是非交互式的,覆盖文件内容,可能导致文件内容丢失 —— 提前备份
注:“2>” 只能识别错误的输出结果,若结果是正确的,将以 null 作为输入,会导致文件内容丢失
bash 的输入重定向
- < —— 输入重定向符号
wc —— 统计字符串
- 命令:wc [选项] [文件名]
- -c —— 统计字数(字符)
- -w —— 统计字符串数量
- -l —— 统计行数
例1:使用 wc 命令配合输入重定向,统计一个文件中的内容
wc < anaconda-ks.cfg # 统计 anaconda-ks.cfg 中行数、字符串数、字符数
49 122 1273 # 行数、字符串数、字符数
例2:空格和换行符 “\n” 也算作一个字符,行数统计的实际就是 “\n” 换行符出现的次数
echo "hello world" > a.txt
wc < a.txt # 1 2 12
echo -n "hello world" > a.txt # 使用 -n 选项,取消掉结尾的 "\n",观察变化
wc < a.txt # 0 2 11
注:字符之间只要有间隔就表示是一个字符串,有 “\n” 换行符,才算做一行,换行符以及空格等任何字符都算作字符数
命令连接符
命令连接符 —— 多命令顺序执行
多命令执行符 | 格式 | 作用 |
---|---|---|
; | 命令1 ; 命令2 | 多个命令顺序执行,命令之间没有任何逻辑关系 |
&& | 命令1 && 命令2 | 当命令1正确执行,命令2才会执行,否则不执行 |
|| | 命令1 || 命令2 | 当命令1执行不正确,命令2才执行,只执行一个命令 |
例1:重启网卡
ifdown ens33 ; ifup ens33 # 顺序的依次执行两条命令,关闭、再启动网卡
例2:使用 test 命令判断文件是不是普通文件,配合命令连接符,输出 yes 或 no
test -f /root/anaconda-ks.cfg # 没有任何返回结果
echo $? # 判断上一天命令是否成功,0 表示成功
test -f /dev/sr0 && echo yes || echo no # test 命令判断成功,则输出 yes,否则输出 no
test -f /root/anaconda-ks.cfg && echo yes || echo no
过滤&搜索
grep、find、、、locate
grep 命令 —— 行提取命令
- 格式:grep [选项] “关键词” 文件名 —— 提取文件中包含 “关键词” 的那一行
- -A 数字 —— 列出符合条件的行,并将连续列出后续 n 行
- -B 数字 —— 列出符合条件的行,并将连续列出前面 n 行
- -c —— 统计包含字符串的行一共几行
- -i —— 忽略大小写
- -n —— 输出行号
- -v —— 反向查找(取反)
- –color=auto —— 搜索出的关键词高亮显示(默认存在的别名)
例1:列出 /etc/passwd 文件中带有 “root” 关键词的行
grep "root" /etc/passwd
#root: x :0:0:root:/root:/bin/bash
#operator:x :11:0:operator:/root:/sbin/nologin
例2:添加 -n 选项,可输出包含 “root” 行的行号
grep -n "root" /etc/passwd
#1 : root:x:0:0:root:/root:/bin/bash
#10: operator:x:11:0:operator:/root:/sbin/nologin
例3:添加 -n 和 -A 选项,-A 选项可以显示包含关键字的行以外的,后续的指定行数
grep -n -A 1 "root" /etc/passwd
例4:添加 -n 和 -B 选项,-B 选项可以显示包含关键字的行以外的,前面的指定行数
grep -n -B 1 "root" /etc/passwd
例5:统计包含 “root” 关键字行的行数
grep -c "root" /etc/passwd
netstat -anpt | grep :22 —— 常用,过滤查看指定端口的状态
find 和 grep 的区别
- grep —— 行提取命令,把符合条件的行从整个字符范围内取出
- find —— 遍历式查询
- 在系统指定范围内,查询该文件所在路径 —— 准,但是不快
- locate —— 数据库查询
- 配合数据库更新命令 updatedb —— 快,但是不准,某些文件不会被数据库文件所记录
补充:Windows 中类似 locate 的工具 —— Everything,建立数据库查询
通配符
以及管道符补充
通配符功能介绍
通配符 | 作用 |
---|---|
? | 匹配一个任意字符 |
* | 匹配 0 个或任意多个字符,也就是可以匹配任何内容 |
[] | 匹配括号中任意一个字符,但是是括号内的指定范围,如 [abc] 是匹配 abc 其中一个 |
[-] | 匹配括号中任意一个字符,“-” 代表一个范围,如 [a-b] 同样是匹配 abc 其中一个 |
[^] | 逻辑非,表示匹配不是括号内的一个字符,如 [^0-9] 代表匹配一个不是数字的字符 |
例1:创建不同字符组合的文件,使用通配符进行过滤搜索
- 使用 26 个英文字母分别创建文件,大小写分别创建
touch 1.{a..z} 1.{A..Z}
- 使用 find 命令,按名称进行过滤搜索
find ./ -name "1.[a-c]" # 过滤搜索 1.a、1.b、1.c
find ./ -name "1.[a-Z]" # 只能小写字母到大写字母搜索(ASCII 编码顺序)
find ./ -name "1.[a-zA-Z]" # 同样是搜索所有大小写字母
例2:其它对文件名搜索、查看类操作的命令
- ls 命令 —— ls *、ls ?abc、ls [0-9]*、ls [^0-9]*、、、、、、
注:ls、mv、cp —— 只要是对文件名操作的命令,都可以使用通配符
管道符
-
格式:命令1 | 命令2
- 将命令1 的标准输出作为命令2 的标准输入
-
格式:命令1 | xargs 命令2
- 将命令1 的标准输出当做命令2 的执行参数,默认逐个处理
例:注意管道符添加 “xargs” 的区别
find /etc -name "*.txt" | cat # 列出文件名称,将搜索结果当作字符串
find /etc/ -name "*.txt" | xargs # 列出各文件中的内容,将各文件名当作 cat 的标准输入
注:管道符将前面的命令的输出当作第二条命令的输入,必须符合标准输入,xargs 会将输出的内容逐条处理
特殊符号
Bash 中其它特殊符号
符号 | 作用 |
---|---|
‘’ | 单引号,在单引中的所有特殊符号都没有特殊含义 |
“” | 双引号,在双引号中的会保留部分符号的特殊含义 |
`` | 反引号,反引号用于引用命令的输出结果,对结果取值 |
$() | 作用同反引号,更推荐的方式 |
() | 小括号中的命令会在子 shell 中运行 |
{} | 大括号中的命令会在当前 shell 中执行,但可用于变量变形与替换 |
[] | 中括号用于对变进行条件判断 |
# | 井号开头代表注释 |
$ | 用于调用变量的值 |
\ | 转义符,用于取消特殊符号的作用,输出特殊符号本身 |
例1:创建变量并复制,并使用 " " 取出变量的值—— ∗ ∗ " 取出变量的值 —— ** "取出变量的值——∗∗ 调用变量**
- name=nc1239 —— 创建变量 name,赋值为 nc1239
- echo $name —— 使用 $name 取出变量的值
例2:分别测试 “$” 在单双引号中是否能生效 —— 单引号和双引号
- echo “$name” —— 双引号中的特殊符号可以生效
- echo ‘$name’ —— 单引号范围中的任何符号都不具备特殊作用和含义
例3:输出 “\” 符号本身 —— “\” 的特殊作用是换行 —— “\” 转移符
- echo “\\” —— 使用转义符 “\” 输出符号 “\” 本身
- echo ‘\’ —— 使用单引号取消其特殊含义,输出 “\” 本身
例4:输出 "hello world! " —— “!” 是有特殊含义的
- echo “hello world! " —— 注意 “!” 后面必须加一个空格,才能正常输出,”!" 不能作为结尾
- echo ‘hello world!’ —— 单引号可以正常输出
例5:使用反引号取出命令的结果,赋值变量 —— 反引号,引用命令结果
- time=`date`—— 反引号的作用是保存和取出命令的结果
- echo $time —— 输出 time 变量的值
- time=$(date) —— 作用相同
注:使用 “$(命令)” 和 `命令` 的功能完全一致,作用就是将命令的结果取出
例6:使用小括号可以新建子 shell 环境,临时执行命令 —— 小括号新建子 shell 环境执行命令
- name=nc1239 —— 新建变量并赋值
- (name=nc123;echo $name) —— 使用小括号重新赋值,并输出测试
- echo $name —— 在当前 shell 环境输出
注:Shell 解释器是可以手动开启的,每执行一次 bash 命令就会开启一个新的 shell 解释器,相应的就会有父 shell 和 子 shell
- 执行 bash 命令前:使用 pstree 查看进程关系
- sshd ---- sshd ---- bash ---- pstree
- 执行 bash 命令后
- sshd ---- sshd ---- bash ---- bash ---- pstree
注:最明显的感觉就是当你新开起一个 shell 后,刚才执行的历史命令调用不出来
注:不同 shell 环境中,内存的空间是不互通的
- num=100 --》echo $num —— 新建的终端窗口无法调用变量,两个窗口用的不是同一个 shell 解释器
注:不同窗口下的 shell 环境依赖的底层环境是相同的,是平行运行
- ping 192.168.121.121
- pstree —— 打开另一个窗口,同样可以查到 ping 命令的进程
子 shell 和平行 shell:同样加载在内存中,却不在一个作用域范围,变量的作用域不同
例7:大括号只是把命令单独括起来,要执行的整体,而不是新建子 shell —— 大括号在当前 shell 执行
- { echo “hello world”;}—— 大括号左侧和命令之间要留一个空格,命令结束要加 “;”
例8:使用中括号进行条件判断 —— 中括号判断语句
-
判断变量 a 是否大于 100,大于则输出 yes,否则输出 no
- [ “$a” -gt 100 ] && echo yes || echo no
- test “$a” -gt 100 && echo yes || echo no —— 效果相同
-
判断文件类型
- [ -b /dev/sr0 ] && echo yes || echo no
- [ -c /dev/stdin ] && echo yes || echo no
注:[] 和 test 命令功能相同,选项 -f、-r、-gt、、、—— 注意括号内两端留空格
小结
总结
- 在单引号中所有的字符都不具备特殊功能和含义,仅仅是一个字符而已
- 在双引号中,大部分字符都不具备特殊功能和含义,有些符号则可以继续生效。例如 “\”、“$”、``、“!”
- 反引号用于引用命令输出结果 —— 对命令结果取值
- “$” 用于对变量取值
- 小括号会新建一个子 shell,执行命令 —— 作用域不同,子 shell 是独立的,仅是依托关系
- 中括号用于条件判断
注:大括号和小括号的区别
- () 执行一串命令时,需要重新开一个子 shell 进行执行
- {} 执行一串命令时,是在当前 shell 执行
- () 和 {} 都是把一串的命令放在括号里面,并且命令之间用 “;” 分号隔开
- () 最后一个命令可以不用分号结尾
- {} 最后一个命令要用分号结尾
- {} 的第一个命令和左括号之间必须要有一个空格
- () 里的各命令不必和括号有空格
补充:$ —— 调用变量的值
- name=nc1239
- echo $name、echo n a m e 、 e c h o n a m e {name}、echo name name、echonameid、echo ${name}id —— echo $nameid,错误示范
注:大括号括起,表示所有字符是一个整体