标准输出和标准错误输出

好 👍 我给你把这两个命令逐段拆开解释一下。


命令一

nohup du -sh * --exclude=s --exclude=b --exclude=q --exclude=yuanruifeng > rsync.log 2>&1 2>/dev/null &

分解

  1. nohup

    • 让命令在退出当前终端时仍然继续运行(忽略 SIGHUP 信号)。

    • 会默认把标准输入重定向到 /dev/null,并提示 nohup: ignoring input

  2. du -sh * --exclude=...

    • du: 统计目录或文件大小。

    • -s: 总计(summary),只输出一行总大小。

    • -h: 以人类可读方式输出(如 240M)。

    • *: 匹配当前目录下的所有文件/目录。

    • --exclude=xxx: 排除指定名字的目录或文件。

  3. > rsync.log

    • 把标准输出(文件描述符 1)重定向到 rsync.log 文件。

  4. 2>&1

    • 把标准错误(文件描述符 2)也重定向到标准输出(即写入 rsync.log )。

  5. 2>/dev/null

    • 再次把标准错误(文件描述符 2)丢进 /dev/null

    • 注意:这个会覆盖前面的 2>&1 设置,所以最终标准错误不会进 rsync.log,而是被丢弃!

  6. &

    • 把整个命令放到后台执行。

总结

这个命令的效果是:

  • 输出结果写到 rsync.log

  • 错误信息被丢弃(不进日志)。

  • 后台运行,不受退出终端影响。


命令二

nohup du -sh * --exclude=s --exclude=b --exclude=q --exclude=yuanruifeng > rsync.log 2>&1 < /dev/null &

分解

  1. nohup

    • 同上,忽略挂起信号。

  2. du -sh * --exclude=...

    • 同上。

  3. > rsync.log

    • 标准输出写到 rsync.log

  4. 2>&1

    • 错误输出合并到标准输出(进 rsync.log)。

  5. < /dev/null

    • 明确指定标准输入来自 /dev/null(空设备),避免 nohup 输出 “ignoring input”。

  6. &

    • 后台执行。

总结

这个命令的效果是:

  • 输出和错误都写到 rsync.log

  • 不会打印 nohup: ignoring input

  • 后台运行,不受退出终端影响。


两者区别

写法错误输出去哪里是否有 nohup: ignoring input 提示
2>/dev/null 版本 丢掉,不写日志 有时会有提示
< /dev/null 版本 和正常输出一起写进 rsync.log 没提示,最干净

👉 所以:

  • 如果你要保留错误信息 → 用 第二个 < /dev/null 版本。

  • 如果你觉得错误信息没用 → 用 第一个 2>/dev/null 版本。

好问题 👍 你问的 2 是什么、1 是什么、2>&1 怎么理解,这就是 Linux 文件描述符 (file descriptor) 的概念。


基本概念

在 Linux/Unix 中,每个进程启动时都会默认打开 3 个文件描述符:

文件描述符符号含义
0 stdin 标准输入(keyboard、文件、管道等)
1 stdout 标准输出(正常结果输出)
2 stderr 标准错误输出(错误信息)

所以:

  • 1 代表 标准输出

  • 2 代表 标准错误


重定向语法

  1. >

    • 相当于 1>,就是把标准输出重定向。

    • 例如:

      echo hello > out.log
      

      会把正常输出写入 out.log

  2. 2>

    • 表示重定向标准错误。

    • 例如:

      ls notfound 2> error.log
      

      把错误写到 error.log

  3. 2>&1

    • 表示“把 标准错误 (2) 重定向到 标准输出 (1) 所指向的地方”。

    • 举例:

      command > all.log 2>&1
      
      • > all.log:标准输出写到 all.log

      • 2>&1:标准错误跟随标准输出,也写到 all.log

      • 最终,正常结果和错误信息都进了同一个文件。


实际演示

假设有个命令:

ls /etc/passwd /notfound
  • /etc/passwd 存在,会输出到 stdout

  • /notfound 不存在,会输出错误到 stderr

  1. 只保存正常输出:

    ls /etc/passwd /notfound > out.log
    
    • out.log 里只有 /etc/passwd

    • 错误信息仍然在屏幕上。

  2. 只保存错误输出:

    ls /etc/passwd /notfound 2> err.log
    
    • err.log 里只有错误信息 No such file or directory

    • /etc/passwd 在屏幕上。

  3. 两者合并到一个文件:

    ls /etc/passwd /notfound > all.log 2>&1
    
    • all.log 里既有 /etc/passwd 又有错误信息。


✅ 总结:

  • 0 → stdin(输入)

  • 1 → stdout(标准输出)

  • 2 → stderr(错误输出)

  • 2>&1 → 把错误也写到标准输出去的地方


 

👌 我给你详细解释一下 < /dev/null 显式声明输入丢弃 的作用。


1. Linux 命令的三个“流”

每个进程一启动,系统会给它准备三条数据通道:

文件描述符名称默认来源/去向
0 标准输入 stdin 键盘(用户输入)
1 标准输出 stdout 屏幕(正常输出)
2 标准错误 stderr 屏幕(错误信息)

正常情况下:

  • 命令会等着从 stdin(0) 读数据(比如 catread)。

  • 如果后台运行,stdin 没人输入,就会报错或者被 nohup 自动接到 /dev/null,并提示 ignoring input


2. 什么是 /dev/null

  • /dev/null 是一个“黑洞文件”:

    • 写进去的东西全部丢弃

    • 读出来永远是 EOF(空)

所以如果你把输入重定向到 /dev/null

< /dev/null

就等于告诉命令:

“你的输入来源是个空文件,没有东西可读,你别等输入了。”


3. nohup 的默认行为

  • nohup 的设计初衷是让命令在用户退出后继续跑。

  • 如果你不指定输入来源,它会自动帮你把 stdin 重定向到 /dev/null,并打印:

    nohup: ignoring input
    
  • 它只是告诉你:“我把输入忽略掉了”。


4. 显式加 < /dev/null 的作用

如果你自己加了:

command < /dev/null

就等于提前声明:

  • stdin 不需要用户输入,直接丢弃。

  • 这样 nohup 检查时,发现你已经处理好了 stdin,它就不会再输出 “ignoring input” 这行提示。


5. 实际效果对比

没写 < /dev/null

nohup sleep 1000 &
# 输出:nohup: ignoring input and appending output to 'nohup.out'

写了 < /dev/null

nohup sleep 1000 < /dev/null &
# 没有任何多余提示,静默运行

总结

  • < /dev/null = 告诉进程:输入流为空,不要等用户输入。

  • 对交互式命令(catread)来说:立刻遇到 EOF,什么也读不到。

  • 对后台命令 + nohup 来说:去掉 “ignoring input” 提示,让运行更干净。


 


1️⃣ < /dev/null 的作用

< /dev/null把标准输入重定向到空设备,意思是:

  • 命令执行时如果尝试读取标准输入(stdin),就会立即读到 EOF(相当于没有输入)。

  • 常用在后台运行的命令里,防止命令阻塞在等待输入,尤其是使用 nohup& 后台运行时。

例如:

nohup some_command < /dev/null &
  • nohup 默认会忽略输入并给出提示:

    nohup: ignoring input and redirecting stderr to stdout
    
  • 如果你希望完全避免挂起或阻塞,有 < /dev/null> 会更安全。


2️⃣ 为什么我给出的方式可以工作

我写的命令是:

seq -w 01 20 | xargs -I {} -P 20 sh -c 'rsync -P -av wangzeyu _backup/' \
  > rsync-push-20250716.log 2>&1 &

解释:

  1. seq -w 01 20 | xargs -I {} -P 20 sh -c '...'

    • seq 生成 01~20,作为 xargs 的输入。

    • -P 20 表示最多并行 20 个 sh -c

    • 每个 sh -c 执行 rsync

    • 这里 stdin 已经被 seq | xargs 提供了输入,所以不需要 < /dev/null

  2. > rsync-push-20250716.log 2>&1

    • 将 stdout 和 stderr 都重定向到日志文件。

  3. &

    • 后台运行,Shell 不再阻塞。

所以:

  • 不需要 nohup 也能在后台运行。

  • 不需要 < /dev/null,因为 xargs 已经提供了 stdin。

  • 日志统一写入文件。


3️⃣ 如果想加上 < /dev/null,完整写法

seq -w 01 20 | xargs -I {} -P 20 sh -c 'rsync -P -av wangzeyu _backup/' \
  > rsync-push-20250716.log 2>&1 < /dev/null &
  • 这里 < /dev/null 可以保证即便 rsyncsh 想读 stdin,也不会阻塞。

  • 在实际中,rsync 一般不会读 stdin,所以可加可不加。


 

posted on 2025-08-20 21:03  吃草的青蛙  阅读(55)  评论(0)    收藏  举报

导航