# 简介
之前在 shell
快速入门中已经讲了如何构建一个脚本,我们回顾一下:
- 第一行要指定 shell 类型
#!/bin/bash
。 - 完成基本的脚本构建后,增加执行权限
chmod u+x 文件名(u是属主)
。 - 要取消
echo
的换行,就要使用-n
参数echo -n "abcd"
。 - 使用美元符号
$
来引用变量,如果想单纯使用这个符号,要加上转义符\$
。 - 在脚本中自行设置变量时,= 之间不能有空格,不然 shell 会认为是命令而不是变量
var=100
。
本文会接着介绍其他与脚本编程相关的知识。
# 命令替换
shell
脚本最有用的特性之一就是可以从命令输出中提取信息,请 get
关键词,命令输出和提取信息。
该特性有两种实现方式:
- 使用反引号(就是
Tab
键上面那个)
#date 命令可以得到当前时间 cyan@cyan-virtual-machine:~/Templates$ cat new_File | |
214391248 | |
cyan@cyan-virtual-machine:~/Templates$ cat new_File | |
214391248 | |
cyan@cyan-virtual-machine:~/Templates$ echo `date` > new_File | |
cyan@cyan-virtual-machine:~/Templates$ cat new_File | |
2022年 08月 01日 星期一 10:42:33 CST | |
cyan@cyan-virtual-machine:~$ var=`date` | |
cyan@cyan-virtual-machine:~$ echo $var | |
2022年 08月 01日 星期一 10:21:55 CST |
- 使用
$()
,有些shell
不支持这种
cyan@cyan-virtual-machine:~$ var=$(date) | |
cyan@cyan-virtual-machine:~$ echo $var | |
2022年 08月 01日 星期一 10:23:19 CST |
命令替换会创建一个子 shell
来运行对应命令,子 shell
是由运行脚本的 shell
创建的一个独立的子 shell
。因此,该子 shell
所执行的命令是无法使用脚本中所创建的变量的。在命令行提示符下使用路径./ 来运行命令,也会创建子 shell
关于 date
命令,你如果希望得到自己希望的格式化结果
cyan@cyan-virtual-machine:~$ date +%y-%m-%d\ %H:%M:%S | |
22-08-01 10:25:33 |
# 重定向
从这里开始,你就算接触流这个东西了,输入流输出流,重定向就是对流的方向重新定义(你现在可以这么理解)。
# 标准输出重定向
举一个例子, echo
将数据打印到屏幕上(标准输出流),那么我们可以对 echo
的流的方向重新指向
cyan@cyan-virtual-machine:~/Templates$ cat new_File | |
214391248 | |
cyan@cyan-virtual-machine:~/Templates$ cat new_File | |
214391248 | |
cyan@cyan-virtual-machine:~/Templates$ echo `date` > new_File | |
cyan@cyan-virtual-machine:~/Templates$ cat new_File | |
2022年 08月 01日 星期一 10:42:33 CST |
从上面代码可以看到, echo
通过 >
符号,将输出重定向到 new_File
这个文件里面了。并且先清空文件原本内容。
command >> outputfile
是追加模式。
# 标准输入重定向
将文件内容重定向到命令: command < inputfile
# wc 命令可以对数据文本进行计数:文本行数 文本字数 文本字节数 | |
cyan@cyan-virtual-machine:~/Templates$ wc < new_File | |
1 6 43 |
这里有个需要注意的地方就是, <
是改变标准输出(屏幕), >
是改变标准输入(键盘)。重定向不是代替参数,而是改变标准输入输出。
比如以下命令就不行
echo < new_File |
echo
的使用格式是 echo 参数
,重定向不能替代参数。
wc
后面接收的可以是标准输入
cyan@cyan-virtual-machine:~/Templates$ wc | |
line1 | |
line2 | |
2 2 12 # 使用 ctrl+d 结束命令并统计 |
# 内联重定向
可以参考:https://blog.csdn.net/qq_38156104/article/details/110375889
替换文件为文本,数据流向命令: command << 特殊字符
数据的开始和结束文本标记要一致。本质就是将开始符和结束符之间的数据传给命令
cyan@cyan-virtual-machine:~/Templates$ wc <<EOF | |
> 123 | |
> 4142 | |
> EOF | |
2 2 9 |
# 管道
一个命令的标准输出作为另一个命令的标准输入
rpm -qa > rpm.list | |
sort < rpm.list |
rpm
命令通过 RedHat
包管理系统 ( RPM
) 对系统上安装的软件包进行管理。配合 -qa
选项使用时,会生成已安装包的列表,尽管不会排序。(虽然我在终端执行上面两个命令没啥反应)
重定向在命令之间数据传输比较繁琐,使用管道 |
解决。
command | command |
为了更好了解管道,我写了一个 c
程序,文件为 test.c
。
#include <stdio.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
#include <sys/time.h> | |
#include <fcntl.h> | |
int main() | |
{ | |
struct timeval start,end; | |
int fd = open("./tmp",O_RDONLY); | |
int i = 0; | |
char bf[10]; | |
for(i;i < 10;i++) | |
{ | |
gettimeofday(&start,NULL); | |
read(fd,bf,10); | |
gettimeofday(&end,NULL); | |
//printf("%s",bf); | |
printf("%d",end.tv_usec - start.tv_usec); | |
} | |
close(fd); | |
return 0; | |
} |
在 linux
中可以用 cat
查看,如果在后面接上 sort
命令
cat test.c | sort |
其输出结果为
{ | |
} | |
{ | |
} | |
char bf[10]; | |
close(fd); | |
for(i;i < 10;i++) | |
gettimeofday(&end,NULL); | |
gettimeofday(&start,NULL); | |
#include <fcntl.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <sys/time.h> | |
#include <unistd.h> | |
int fd = open("./tmp",O_RDONLY); | |
int i = 0; | |
int main() | |
printf("%d",end.tv_usec - start.tv_usec); | |
//printf("%s",bf); | |
read(fd,bf,10); | |
return 0; | |
struct timeval start,end; |