2>&1 前后位置不同分析

本文详细解析了Linux命令行中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) 

      可以考虑一下不同的dup2()调用序列会产生怎样的文件共享结构。请参考APUE 3.10, 3.12 
<think> 我们正在处理用户的问题:在执行包含 `where python >nul 2>&1` 的代码时出现 'FINDSTR: 错误的命令行' 错误。 用户提供的引用内容并不直接相关,但我们可以根据之前关于FINDSTR错误的解决方案来回答。 回顾用户的问题:用户在运行类似 `where python >nul 2>&1` 的代码块时遇到FINDSTR错误。但是,我们注意到用户提供的代码示例中并没有直接出现FINDSTR命令。因此,我们需要推测上下文。 通常,`where`命令用于查找可执行文件的位置,而`>nul 2>&1`用于抑制输出。那么,用户可能在更复杂的命令链中使用了FINDSTR,例如: where python 2>&1 | findstr "错误" 在这种情况下,如果FINDSTR命令的语法不正确,就会报错。 根据之前总结的FINDSTR常见错误,我们可以分析1. 可能是管道传递到FINDSTR的内容包含了FINDSTR无法处理的特殊字符,但通常不会。 2. 更可能的是,FINDSTR命令本身的写法有误。 注意:用户提供的示例代码片段是`where python >nul 2>&1`,这里并没有使用管道和FINDSTR。所以用户可能在别的地方使用了FINDSTR。 然而,用户明确提到“在执行包含 'where python >nul 2>&1' 等代码时出现 'FINDSTR: 错误的命令行' 错误”,所以可能是整个命令链的一部分,比如: where python >nul 2>&1 && findstr ... 或者 where python 2>&1 | findstr ... 我们假设用户在使用类似这样的命令: where python 2>&1 | findstr "python" 那么,错误可能出现在FINDSTR部分。 常见原因及解决方案: 1. 搜索字符串包含特殊字符且未转义或未用引号包裹。 - 例如:`findstr (something` 会出错,因为`(`是特殊字符。 - 解决方案:使用`/C:"字符串"`或者`/L`(禁用正则)或者用双引号包裹整个字符串。 2. 搜索字符串为空,或者管道传递过来的数据导致FINDSTR没有收到正确的参数。 针对用户的情况,我们重点检查管道后面的FINDSTR命令的语法。 示例修复: 原命令(假设): where python 2>&1 | findstr python 如果这个命令报错,可能是因为`python`这个词在FINDSTR中作为正则表达式解析时有问题(虽然这里不会,因为只是一个单词),但更可能是其他问题,比如FINDSTR命令行中其他参数错误。 另外,错误信息是“错误的命令行”,说明FINDSTR认为命令行参数不正确。 可能的错误写法: findstr:8080 # 错误,因为命令行参数格式不对 正确写法: findstr ":8080" # 注意搜索字符串用双引号包裹 因此,我们建议用户检查FINDSTR命令的写法,特别是: - 确保搜索字符串用双引号包裹。 - 如果搜索字符串包含特殊字符,使用`/C:"字符串"`或转义。 但是,用户并没有给出具体的FINDSTR命令,所以我们需要提供一般性建议。 另外,用户命令中`>nul 2>&1`是重定向,不会导致FINDSTR错误,除非FINDSTR命令本身有误。 因此,我们给出以下步骤: 步骤1:检查FINDSTR命令的语法 - 确保搜索字符串被双引号包围,特别是当字符串包含空格或特殊字符时。 - 如果不需要正则表达式,使用`/L`选项进行字面搜索。 步骤2:单独测试FINDSTR命令 - 先不使用管道,直接用FINDSTR搜索一个已知文件,确保命令正确。 步骤3:检查管道输入 - 如果管道前面的命令(如`where python 2>&1`)产生了FINDSTR无法处理的输出(比如空输出),也可能导致问题。可以尝试先运行前半部分命令,看输出是否正常。 步骤4:考虑使用临时文件 - 如果管道有问题,可以将输出重定向到临时文件,再用FINDSTR处理。 示例修正: 错误命令(假设): where python 2>&1 | findstr /C:python 修正1(使用引号): where python 2>&1 | findstr /C:"python" 修正2(如果搜索字符串是纯文字): where python 2>&1 | findstr /L "python" 另外,注意在批处理中,特殊字符如`>`、`<`、`|`等都可能需要转义(用^)或用引号。 由于用户没有给出完整命令,我们只能提供通用方案。 根据用户描述,他们是在执行包含`where python >nul 2>&1`的代码块时遇到错误。注意,这个代码块本身并不包含FINDSTR,所以可能是该代码块前后的命令导致的。需要检查整个脚本。 因此,我们建议用户检查整个命令链,特别是FINDSTR命令的书写。 生成的相关问题: 1. 如何在批处理中转义特殊字符? 2. 如何调试批处理脚本中的管道错误? 3. 如何使用FINDSTR搜索包含空格的字符串? 现在,我们按照要求组织答案。 </think> ### 解决 `where python >nul 2>&1` 中的 FINDSTR 命令行错误 当在批处理脚本中执行类似 `where python >nul 2>&1` 的代码时出现 **"FINDSTR: 错误的命令行"** 错误,通常是由于以下原因造成的: --- #### **1. 管道操作符使用错误** **原因**: 在 `where` 命令后直接使用管道符 `|` 连接 `FINDSTR` 时,若语法不正确会报错: ```batch REM 错误示例(管道符使用不当) where python | findstr "python" >nul 2>&1 ``` **解决方案**: ```batch REM 正确形式:确保管道符两边有空格 where python 2>&1 | findstr /I "python" > nul ``` - `2>&1` 将错误输出重定向到标准输出 - `/I` 忽略大小写 - `> nul` 抑制所有输出[^1] --- #### **2. FINDSTR 特殊字符未转义** **原因**: 搜索词中包含正则特殊字符(如 `.` `*` `|`),但未转义或未用 `/L` 参数: ```batch REM 错误示例(未处理特殊字符) where python.exe | findstr ".exe" ``` **解决方案**: ```batch REM 方案1:转义特殊字符 where python.exe | findstr "\.exe" >nul REM 方案2:使用 /L 强制字面匹配 where python.exe | findstr /L ".exe" >nul ``` --- #### **3. 命令组合逻辑错误** **原因**: 尝试用 `&&` 连接 `where` 和 `FINDSTR` 导致语法混乱: ```batch REM 错误示例(无效命令链) where python >nul 2>&1 && findstr "success" log.txt ``` **解决方案**: 用 `if errorlevel` 明确判断状态: ```batch where python >nul 2>&1 if %errorlevel% equ 0 ( echo Python存在 >> log.txt ) else ( echo Python未找到 >> log.txt ) ``` --- #### **完整修正示例** ```batch @echo off where python 2>&1 | findstr /I /C:"python.exe" > nul if %errorlevel% equ 0 ( echo Python已安装 ) else ( echo Python未找到 ) ``` - `/I`:忽略大小写 - `/C:"..."`:精确匹配字符串 - `> nul`:隐藏所有输出[^1] --- ### 关键排查步骤 1. **隔离测试**: 单独运行 `FINDSTR` 命令验证语法 ```batch echo test | findstr "test" ``` 2. **检查重定向**: 确保 `>` 和 `2>&1` 之间无空格 ```batch REM 正确 command >nul 2>&1 REM 错误 command > nul 2>&1 ``` 3. **编码验证**: 使用 `chcp` 检查控制台编码是否匹配(推荐65001 UTF-8) ```batch chcp 65001 ``` --- ### 相关问题 1. 如何在批处理中正确组合 `where` 和 `findstr` 命令? 2. 重定向 `2>&1` 和 `>nul` 的区别是什么? 3. 如何检测Windows环境变量是否存在特定路径? 4. 批处理中 `%errorlevel%` 和 `if errorlevel` 的使用场景有何不同? 5. 如何避免批处理脚本中的特殊字符解析错误? > 提示:复杂命令建议使用 PowerShell 的 `Get-Command` 替代 `where`,例如: > ```powershell > if (Get-Command python -ErrorAction SilentlyContinue) { "存在" } > ```[^1]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值