#### 重定向
最常见的标准输入(stdin)、标准输出(stdout)和标准错误输出(stderr)的文件描述符分别是0、1和2,其中0、1、2也可以认为是它们的数字代号。对于输出信息,可以认为是打印在屏幕上的信息,而没给出错误的就是标准输出,给出错误提示的是标准错误输出,当然这样说明有失偏颇,但是易于理解。还可以自定义自己的描述符,实现高级重定向,在以后的文章中可能会介绍一下它们的用法。
> 标准输入 = /dev/stdin = 代号0 = <符号(注意,没有包含<<符号)。
>
> 标准输出 = /dev/stdout = 代号1 = >或>>符号。
>
> 标准错误输出 = /dev/stderr = 代号2 = 使用2>或2>>符号。
注意,上面的/dev/std{in,out,err}分别是0、1、2**默认的输出目标,当重定向后,就不再使用这些目标**。具体见后文。
、2>实现的是覆盖功能,>>、2>>实现的是追加的功能,但是注意"<<"不是追加功能,而是表示此处生成文档(here document),在后面cat和重定向配合的内容里有说明。此外,还有<<<,它表示此处字符串(here string),也见下文。
有时候,使用"-"也表示/dev/stdin。如:
~~~
[root@xuexi ~]# cat /etc/fstab | cat -
~~~
**脚本中常见2>&1和&>以及&>>的符号,它们都表示将stdout和stderr都重定向到同一个地方去,即重定向所有输出内容**。如最常见的"&> /dev/null"。
**注意:**
**(1).重定向操作是shell最先解析到的,在执行命令之前,重定向就会先打开文件以确定输入、输出的位置。如果是重定向输出操作,则先截断文件使其为空。**
**(2)./dev/stdin、/dev/stdout、/dev/stderr等设备只是数据默认的流向目标(严格地说是文件描述符0、1、2的输出目标),它们不等价于"标准输入0、标准输出1、标准错误2"。之所以称为"重定向",就是将数据的流向改变,不再输入到这些默认设备中。**
**(3).重定向的顺序很重要。**
例如 **ls / >file1 2>&1** 表示先打开file1作为标准输出(fd=1)的目的地,然后再将标准错误绑定到标准输出(已经是file1)上,这样无论是标准错误还是标准输出都重定向到file1中。它等价于 **ls / &>file1** 。"&"符号表示描述符重用(fd 2 duplicate from fd 1),有些人将其翻译为文件描述符的复制, 2>&1 翻译为标准错误是标准输出的复制、副本,这样的翻译非常容易产生误解,且很难结合已有知识去理解清楚。关键是很多书上就是这么解释的,让人费解,误导一大片人以为这是高级重定向。**直接将其理解为文件描述符2绑定到文件描述符1上,或者文件描述2重用文件描述符1即可。**
**而 ls / 2>&1 >file1 表示先将标准错误绑定到标准输出,此时标准输出还是/dev/sdtout(即屏幕),因此标准错误的输出目标是/dev/stdout(屏幕)。之后再打开file1作为标准输出的目标。因此,它最终将标准错误重定向到/dev/stdout,将标准输出重定向到file1。可以让ls命令产生错误来测试, ls dlfjasl 2>&1 >file1 ,结果将直接显示在屏幕上**。
..
## cat和重定向配合
配合cat使用可以分行输入内容到文件中。
~~~
[root@xuexi tmp]# cat <<eof>log.txt # 覆盖的方式输入到log.txt
> this is stdin character
> eof
~~~
也可以使用下面的方法。
~~~
[root@xuexi tmp]# cat >log1.txt <<eof
> this is stdin character first!
> eof
~~~
一方面,eof部分都必须使用"<<eof",**它表示here document,此后输入的内容都作为一个document输入给cat。既然是document,那就肯定有document结束符标记document到此结束,结束符使用的是here document后的字符,**例如此处为eof。其实不使用eof,使用其他字符也是一样的,但document的结束符也必须要随之改变。如:
~~~
[root@xuexi ~]# cat <<abcx
> 123
> 345
> abcx
123
345
~~~
另一方面,>log1.txt表示将document的内容覆盖到log1.txt文件中,如果是要追加,则使用>>log1.txt。所以,追加的方式如下:
~~~
[root@xuexi tmp]# cat >>log1.txt <<eof
> this is stdin character first!
> eof
~~~
或
~~~
[root@xuexi tmp]# cat <<eof>>log1.txt
> this is stdin character first!
> eof
~~~
- Linux
- linux常用命令
- awk
- cp
- scp
- mv
- screen工具
- rsync
- Linux设置静态IP
- vim常用
- ssh免密登录
- linux挂载磁盘和开机自动挂载
- 文件的时间戳
- 重定向
- 防火墙
- Vultr 服务器利用快照更换IP
- ss
- node-yarn
- ES安装向导
- lnmp/lamp
- windows安装mysql
- windows安装nginx
- Let'sEncrypt 免费通配符/泛域名SSL证书
- 开机自动挂载硬盘
- 普通用户提权
- ELK日志分析系统
- Docker
- docker
- centos7安装docker
- Centos7安装redis
- CentOS 7 使用Docker搭建Nginx
- CentOS 7 使用Docker搭建Jenkins
- CentOS 7 使用Docker搭建Zookeeper
- CentOS 7 使用Docker搭建Tomcat
- CentOS 7 使用Docker搭建Mysql
- CentOS 7 使用Docker搭建PHP环境
- 使用docker搭建Swagger
- docker阿里云私有仓库
- docker zookeeper集群
- docker部署ES
- docker之java容器运行外置springboot-jar
- docker部署owncloud云盘
- ETCD
- centos7部署etcd节点
- Dockerfile
- Docker-compose
- gitlab.yml
- db.yml
- 安装docker-compose
- gitlab-docker-compose.yml
- nginx-docker-compose.yml
- Mysql
- mysql开启远程访问及相关权限控制
- mysql授权
- mysql快速导出导入大数据
- mysql单机备份
- binlog日志
- shell
- 经典案例
- 俄罗斯方块游戏
- 系统初始化
- 服务器监控
- go基础环境
- shell.监控日志.elk
- shell.检查各服务脚本
- shell.删除文件脚本
- shell.守护进程
- shell.数据库
- shell.Ansible
- shell.dev
- shell.ftp环境
- shell.docker环境
- shell.k8s环境
- k8s.二进制安装
- K8s.一主多从
- k8s.三主两从高可用
- k8s.检查服务与配置
- k8s.jenkins
- k8s.gitlab
- go-install.sh
- jenkins-install.sh
- node-install.sh
- redis-install.sh
- zabbix-install.sh
- zabbix-dockerfile.sh
- nginx-install.sh
- shell变量
- 用户自定义变量
- 环境变量
- shell特殊变量
- shell条件判断
- 流程控制
- shell运算符
- Shell _printf
- shell_test
- shell函数
- 输出重定向
- 网络相关
- 安全相关
- 堡垒机部署
- 区块链威胁情报共享平台
- 签名与验签
- 浅谈区块链
- 智能合约
- 黄金币GTF智能合约
- 节点
- 以太坊公链私链geth同步
- 比特节点同步
- BTC节点错误解决方法
- eth硬分叉
- omni钱包节点搭建
- 架构
- K8s
- 搭建k8s集群完整篇
- 二进制部署k8s
- Devops
- git
- Jenkins
- svn
- 禅道
- CI/CD
- docker+jenkins+golang持续集成持续交付(CI/CD)
- 项目部署
- config.env
- docker-compose.yml
- Dockerfile模板
- .dockerignore
- run.sh
- nginx.conf模板
- 跨域
- jenkins配置
- 测试
- Python