标准输出和标准错误输出
好 👍 我给你把这两个命令逐段拆开解释一下。
命令一
nohup du -sh * --exclude=s --exclude=b --exclude=q --exclude=yuanruifeng > rsync.log 2>&1 2>/dev/null &
分解
-
nohup-
让命令在退出当前终端时仍然继续运行(忽略 SIGHUP 信号)。
-
会默认把标准输入重定向到
/dev/null,并提示nohup: ignoring input。
-
-
du -sh * --exclude=...-
du: 统计目录或文件大小。 -
-s: 总计(summary),只输出一行总大小。 -
-h: 以人类可读方式输出(如240M)。 -
*: 匹配当前目录下的所有文件/目录。 -
--exclude=xxx: 排除指定名字的目录或文件。
-
-
> rsync.log-
把标准输出(文件描述符 1)重定向到
rsync.log文件。
-
-
2>&1-
把标准错误(文件描述符 2)也重定向到标准输出(即写入
rsync.log)。
-
-
2>/dev/null-
再次把标准错误(文件描述符 2)丢进
/dev/null。 -
注意:这个会覆盖前面的
2>&1设置,所以最终标准错误不会进rsync.log,而是被丢弃!
-
-
&-
把整个命令放到后台执行。
-
总结
这个命令的效果是:
-
输出结果写到
rsync.log。 -
错误信息被丢弃(不进日志)。
-
后台运行,不受退出终端影响。
命令二
nohup du -sh * --exclude=s --exclude=b --exclude=q --exclude=yuanruifeng > rsync.log 2>&1 < /dev/null &
分解
-
nohup-
同上,忽略挂起信号。
-
-
du -sh * --exclude=...-
同上。
-
-
> rsync.log-
标准输出写到
rsync.log。
-
-
2>&1-
错误输出合并到标准输出(进
rsync.log)。
-
-
< /dev/null-
明确指定标准输入来自
/dev/null(空设备),避免nohup输出 “ignoring input”。
-
-
&-
后台执行。
-
总结
这个命令的效果是:
-
输出和错误都写到
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>,就是把标准输出重定向。 -
例如:
echo hello > out.log会把正常输出写入
out.log。
-
-
2>-
表示重定向标准错误。
-
例如:
ls notfound 2> error.log把错误写到
error.log。
-
-
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。
-
只保存正常输出:
ls /etc/passwd /notfound > out.log-
out.log里只有/etc/passwd -
错误信息仍然在屏幕上。
-
-
只保存错误输出:
ls /etc/passwd /notfound 2> err.log-
err.log里只有错误信息No such file or directory -
/etc/passwd在屏幕上。
-
-
两者合并到一个文件:
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) 读数据(比如
cat、read)。 -
如果后台运行,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= 告诉进程:输入流为空,不要等用户输入。 -
对交互式命令(
cat、read)来说:立刻遇到 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 &
解释:
-
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。
-
-
> rsync-push-20250716.log 2>&1-
将 stdout 和 stderr 都重定向到日志文件。
-
-
&-
后台运行,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可以保证即便rsync或sh想读 stdin,也不会阻塞。 -
在实际中,
rsync一般不会读 stdin,所以可加可不加。
浙公网安备 33010602011771号