重定向

基本概念  (这是理解后面的知识的前提,请务必理解)

  a、 I/O重定向通常与 FD有关,shell的FD通常为10个,即 0~9;

  b、 常用FD有3个,为0(stdin,标准输入)、1(stdout,标准输出)、2(stderr,标准错误输出),默认与keyboard、monitor有关;

  c、 用 < 来改变读进的数据信道(stdin),使之从指定的档案读进;

  d、 用 > 来改变送出的数据信道(stdout, stderr),使之输出到指定的档案;

  e、 0 是 < 的默认值,因此 < 与 0<是一样的;同理,> 与 1> 是一样的;

  f、 在IO重定向 中,stdout 与 stderr 的管道会先准备好,才会从 stdin 读进资料;

  g、 管道“|”(pipe line):上一个命令的 stdout 接到下一个命令的 stdin;

  h、 tee 命令是在不影响原本 I/O 的情况下,将 stdout 复制一份到档案去;

  i、 bash(ksh)执行命令的过程:分析命令-变量求值-命令替代(``和$( ))-重定向-通配符展开-确定路径-执行命令;

  j、 ( ) 将 command group 置于 sub-shell 去执行,也称 nested sub-shell,它有一点非常重要的特性是:继承父shell的Standard input, output, and error plus any other open file descriptors。

  k、 exec 命令:常用来替代当前 shell 并重新启动一个 shell,换句话说,并没有启动子 shell。使用这一命令时任何现有环境都将会被清除。exec 在对文件描述符进行操作的时候,也只有在这时,exec 不会覆盖你当前的 shell 环境。

编辑本段基本IO

  cmd > file 把 stdout 重定向到 file 文件中;

  cmd >> file 把 stdout 重定向到 file 文件中(追加);

  cmd 1> file 把 stdout 重定向到 file 文件中;

  cmd > file 2>&1 把 stdout 和 stderr 一起重定向到 file 文件中;

  cmd 2> file 把 stderr 重定向到 file 文件中;

  cmd 2>> file 把 stderr 重定向到 file 文件中(追加);

  cmd >> file 2>&1 把 stdout 和 stderr 一起重定向到 file 文件中(追加);

  cmd < file >file2 cmd 命令以 file 文件作为 stdin,以 file2 文件作为 stdout;

  cat <>file 以读写的方式打开 file;

  cmd < file cmd 命令以 file 文件作为 stdin;

  cmd << delimiter Here document,从 stdin 中读入,直至遇到 delimiter 分界符。

编辑本段进阶IO

  >&n 使用系统调用 dup (2) 复制文件描述符 n 并把结果用作标准输出;

  <&n 标准输入复制自文件描述符 n;

  <&- 关闭标准输入(键盘);

  >&- 关闭标准输出;

  n<&- 表示将 n 号输入关闭;

  n>&- 表示将 n 号输出关闭;

  上述所有形式都可以前导一个数字,此时建立的文件描述符由这个数字指定而不是缺省的 0 或 1。如:

  ... 2>file 运行一个命令并把错误输出(文件描述符 2)定向到 file。

  ... 2>&1 运行一个命令并把它的标准输出和输出合并。(严格的说是通过复制文件描述符 1 来建立文件描述符 2 ,但效果通常是合并了两个流。)

  我 们对 2>&1详细说明一下 :2>&1 也就是 FD2=FD1 ,这里并不是说FD2 的值 等于FD1的值,因为 > 是改变送出的数据信道,也就是说把 FD2 的 “数据输出通道” 改为 FD1 的 “数据输出通道”。如果仅仅这样,这个改变好像没有什么作用,因为 FD2 的默认输出和 FD1的默认输出本来都是 monitor,一样的! 但是,当 FD1 是其他文件,甚至是其他 FD 时,这个就具有特殊的用途了。请大家务必理解这一点。

  exec 0exec 1>outfilename # 打开文件outfilename作为stdout。

  exec 2>errfilename # 打开文件 errfilename作为 stderr。

  exec 0<&- # 关闭 FD0。

  exec 1>&- # 关闭 FD1。

  exec 5>&- # 关闭 FD5。

 

 

1. cmd >a 2>a 和 cmd >a 2>&1 为什么不同?

cmd >a 2>a :stdout和stderr都直接送往文件 a ,a文件会被打开两遍,由此导致stdout和stderr互相覆盖。
cmd >a 2>&1 :stdout直接送往文件a ,stderr是继承了FD1的管道之后,再被送往文件a 。a文件只被打开一遍,就是FD1将其打开
他们的不同点在于:

cmd >a 2>a 相当于使用了FD1、FD2两个互相竞争使用文件 a 的管道;
而cmd >a 2>&1 只使用了一个管道FD1,但已经包括了stdout和stderr。
从IO效率上来讲,cmd >a 2>&1的效率更高。

****************************************
经常可以在一些脚本,尤其是在crontab调用时发现如下形式的命令调用

/tmp/test.sh > /tmp/test.log 2>&1
前半部分/tmp/test.sh > /tmp/test.log很容易理解,那么后面的2>&1是怎么回事呢?

要解释这个问题,还是得提到文件重定向。我们知道>和<是文件重定向符。那么1和2是什么?在shell中,每个进程都和三个系统文件相关联:标准输入stdin,标准输出stdout和标准错误stderr,三个系统文件的文件描述符分别为0,1和2。所以这里2>&1 的意思就是将标准错误也输出到标准输出当中

下面通过一个例子来展示2>&1有什么作用:

$ cat test.sh
t
date
test.sh中包含两个命令,其中t是一个不存在的命令,执行会报错,默认情况下,错误会输出到stderr。date则能正确执行,并且输出时间信息,默认输出到stdout

./test.sh > test1.log
./test.sh: line 1: t: command not found

$ cat test1.log
Tue Oct 9 20:51:50 CST 2007
可以看到,date的执行结果被重定向到log文件中了,而t无法执行的错误则只打印在屏幕上

$ ./test.sh > test2.log 2>&1

$ cat test2.log
./test.sh: line 1: t: command not found
Tue Oct 9 20:53:44 CST 2007
这次,stderr和stdout的内容都被重定向到log文件中了。

实际上, > 就相当于 1> 也就是重定向标准输出,不包括标准错误。通过2>&1,就将标准错误重定向到标准输出了,那么再使用>重定向就会将标准输出和标准错误信息一同重定向了。如果只想重定向标准错误到文件中,则可以使用2> file。

linux shell 中"2>&1"含义脚本是:
       nohup /mnt/Nand3/H2000G >/dev/null 2>&1 &
       对于& 1 更准确的说应该是文件描述符 1,而1 一般代表的就是STDOUT_FILENO,实际上这个操作就是一个dup2(2)调用.他标准输出到all_result ,然后复制标准输出到文件描述符2(STDERR_FILENO),其后果就是文件描述符1和2指向同一个文件表项,也可以说错误的输出被合并了.其中0 表示键盘输入 1表示屏幕输出 2表示错误输出.把标准出错重定向到标准输出,然后扔到/DEV/NULL下面去。通俗的说,就是把所有标准输出和标准出错都扔到垃圾桶里面。
       command >out.file 2>&1 &
       command >out.file是将command的输出重定向到out.file文件,即输出内容不打印到屏幕上,而是输出到out.file文件中。 2>&1 是将标准出错重定向到标准输出,这里的标准输出已经重定向到了out.file文件,即将标准出错也输出到out.file文件中。最后一个& , 是让该命令在后台执行。
      
       试想2>1代表什么,2与>结合代表错误重定向,而1则代表错误重定向到一个文件1,而不代表标准输出;
换成2>&1,&与1结合就代表标准输出了,就变成错误重定向到标准输出.

       你可以用
             ls 2>1测试一下,不会报没有2文件的错误,但会输出一个空的文件1;
             ls xxx 2>1测试,没有xxx这个文件的错误输出到了1中;
             ls xxx 2>&1测试,不会生成1这个文件了,不过错误跑到标准输出了;
             ls xxx >out.txt 2>&1, 实际上可换成 ls xxx 1>out.txt 2>&1;重定向符号>默认是1,错误和输出都传到out.txt了。
       为何2>&1要写在后面?
       command > file 2>&1
        首先是command > file将标准输出重定向到file中, 2>&1 是标准错误拷贝了标准输出的行为,也就是同样被重定向到file中,最终结果就是标准输出和错误都被重定向到file中。
       command 2>&1 >file
       2>&1 标准错误拷贝了标准输出的行为,但此时标准输出还是在终端。>file 后输出才被重定向到file,但标准错误仍然保持在终端。

用strace可以看到:
1. command > file 2>&1
这个命令中实现重定向的关键系统调用序列是:
open(file) == 3
dup2(3,1)
dup2(1,2)

2. command 2>&1 >file
这个命令中实现重定向的关键系统调用序列是:
dup2(1,2)
open(file) == 3
dup2(3,1)

<think>首先,用户的问题是基于提供的引用,了解shell重定向的概念、使用方法及示例。引用中涵盖了多个来源,包括输出重定向、输入重定向、错误重定向等。 我需要根据系统级指令来组织我的回答: 1. **行内数学表达式**:使用 `$...$` 格式。虽然这里是关于shell重定向的,可能没有数学表达式,但若有变量或符号,确保正确格式化。 2. **独立公式**:使用 `$$...$$` 并单独成段。同样,可能不适用,除非有公式。 3. **LaTeX语法正确**:确保任何公式正确。 4. **使用中文回答**:整个回答用中文。 5. **生成相关问题**:在回答后添加相关问题部分。 6. **引用标识**:在回答中引用的段落末尾自然地添加引用标识,如 `[^1]`。用户提供了引用编号[1]到[5],所以我应该引用这些来源。 用户指定:"参考站内引用:引用[1]...引用[5]",所以我需要在回答中引用它们。 回答结构:用户上一次的问题是关于快速排序,但现在新问题是关于shell重定向。系统指令说:"尽可能多的参考用户上一次的问题和你的回答",但上一次是快速排序示例,与当前主题无关。我应该专注于当前查询。 组织回答: - **概念**:解释shell重定向的概念。参考引用[2]和[3]。 - **使用方法**:详细描述各种重定向符号及其用法。引用[1],[3],[5]提供符号列表。 - **示例**:提供实际代码示例。引用[3]和[5]给出示例。 使用中文回答。 最后,添加相关问题部分。 结构思路: 1. **介绍概念**:简述shell重定向是什么,目的是什么。引用[^2]。 2. **详细使用方法**:列举符号如 `>`, `>>`, `<`, `2>`, 等。解释每个符号的功能。 - 输出重定向: `>`, `>>` - 输入重定向: `<` - 错误重定向: `2>` - 合并重定向:如 `2>&1`, `>&` 引用[^1],[^3],[^5]。 3. **示例**:提供具体命令示例。例如: - 输出重定向到文件:`ls > file.txt` - 追加输出:`echo "hello" >> file.txt` - 输入重定向:`wc < file.txt` - 错误重定向:`command 2> error.log` 参考引用[^3],[^5]。 4. **总结**:强调重要性,引用[^2]。 在引用段落末尾添加标识:例如,在解释后加 `[^n]`。 最后,**生成相关问题**:添加 "§§相关问题§§" 部分,列出几个相关问题。 相关问题想法: 1. 如何有效地使用文件描述符进行重定向? 2. 什么是 `>/dev/null` 的作用? 3. shell重定向在脚本中的常见应用? 4. 如何处理多个输出流? 确保回答完整、清晰。 </think>### Shell 重定向的概念、使用方法及示例 在 Linux 和 Unix-like 系统中,Shell 重定向是一种强大的功能,用于控制命令的输入和输出流。核心概念是:通过重定向符号,用户可以将命令的标准输入(stdin)、标准输出(stdout)和标准错误(stderr)从默认的终端设备(如显示器)重定向到文件、设备或其他命令中。这主要用于保存输出结果、处理错误信息、或创建管道化的命令序列,从而提高命令行操作的灵活性和效率[^2]。重定向基于文件描述符(fd)实现,其中 0 代表 stdin,1 代表 stdout,2 代表 stderr[^3]。掌握重定向Shell 脚本编写和系统管理的关键技能。 #### 一、基本概念 - **输入重定向**:将命令的输入源从键盘改为文件或其他来源,使用符号如 `<`。 - **输出重定向**:将命令的输出结果从显示器重定向到文件,覆盖或追加内容,使用符号如 `>` 或 `>>`。 - **错误重定向**:将错误信息(stderr)单独重定向到文件或设备,使用符号如 `2>`。 - **合并重定向**:将多个输出流合并到同一文件或设备,使用符号如 `2>&1`(将 stderr 合并到 stdout)。 - 这些功能允许用户灵活管理数据流,例如将日志保存到文件或忽略不必要的噪声[^2][^3]。 #### 二、使用方法及符号详解 Shell 重定向符号根据功能和文件描述符分类使用。以下是常见符号及其语法规则: 1. **输出重定向(stdout)**: - `> file`:将命令的标准输出重定向到文件,覆盖文件内容。语法:`命令 > 文件`。 - `>> file`:将标准输出重定向到文件,追加内容而不覆盖。语法:`命令 >> 文件`。 - 例如,`> file` 也可写作 `1> file`,其中 `1` 是 stdout 的文件描述符;`>` 是 `1>` 的简化形式,中间不能有空格[^5]。 2. **输入重定向(stdin)**: - `< file`:将文件内容作为命令的输入源。语法:`命令 < 文件`。 - `<< tag`:读取终端输入数据,直到遇到指定的结束标记 `tag`(例如 `<< EOF`)。语法:`命令 << tag`。这常用于脚本中输入多行文本[^3][^4]。 3. **错误重定向(stderr)**: - `2> file`:将错误信息重定向到文件,覆盖文件内容。语法:`命令 2> 文件`。 - `2>> file`:将错误信息重定向到文件,追加内容。语法:`命令 2>> 文件`。 4. **合并重定向**: - `2>&1`:将 stderr(fd 2)合并到 stdout(fd 1),使两者输出到同一位置。语法:`命令 > file 2>&1` 或 `命令 &> file`(`&>` 是简化形式)。 - `1>&2`:将 stdout 合并到 stderr,常用于错误处理。 - `fd> file` 或 `fd>> file`:根据指定文件描述符(fd)进行重定向,例如 `2> error.log`[^3][^5]。 5. **特殊设备**: - `/dev/null`:一个“黑洞”设备,丢弃所有重定向的输出(例如忽略错误:`命令 2> /dev/null`)[^5]。 重要规则: - 重定向顺序从左到右执行,例如 `命令 2>&1 > file` 和 `命令 > file 2>&1` 效果不同。 - 文件描述符必须正确指定,以避免意外行为[^5][^3]。 - 在脚本中,重定向常用于日志记录和自动化任务[^2]。 #### 三、示例代码 以下示例基于实际命令展示重定向的使用方式。运行这些命令需在 Linux Shell 环境中(如 Bash)。 1. **输出重定向示例**: - 覆盖输出到文件: ```bash # 清空文件并保存 ls 命令的输出 ls -l > file_list.txt cat file_list.txt # 查看内容 ``` 参考引用[^3]:输出重定向将命令结果保存到文件,便于后续查询。 - 追加输出到文件: ```bash echo "Hello" >> file_list.txt # 不会覆盖原内容 cat file_list.txt # 显示追加后的内容 ``` 2. **输入重定向示例**: - 从文件读取输入: ```bash # 使用 wc 命令统计文件行数 wc -l < data.txt # 输出:文件的行数 ``` - 使用 `<<` 标记输入多行文本: ```bash cat << EOF > output.txt Line 1 Line 2 EOF cat output.txt # 显示内容:Line 1\nLine 2 ``` 此方式通过 `<<` 定义输入窗口,并将输出保存到文件[^4]。 3. **错误重定向示例**: - 分离错误和输出: ```bash rm non_existent_file 2> error.log # 错误信息保存到 error.log cat error.log # 查看错误 ``` - 忽略错误信息: ```bash rm non_existent_file 2> /dev/null # 错误被丢弃 ``` 4. **合并重定向示例**: - 将 stdout 和 stderr 一起保存到文件: ```bash command &> all_output.txt # 等效于 command > all_output.txt 2>&1 cat all_output.txt # 包含所有输出和错误 ``` - 从文件读取输入并重定向输出: ```bash sort < input.txt > sorted_output.txt # 读取 input.txt,输出结果到 sorted_output.txt ``` 参考引用[^3]:这种组合提高了数据处理效率。 #### 总结 Shell 重定向通过简单的符号(如 `>`, `>>`, `<`, `2>`, `2>&1`)实现了强大的输入输出控制,适用于日志记录、错误处理和数据管道化。它能显著提升命令行效率和脚本编写能力[^2][^5]。实践中,建议从基本符号开始测试以避免语法错误(例如空格问题),并逐步探索高级功能如文件描述符合并。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值