如何从cli异步启动外部程序并丢弃其输出?

Ada*_*ski 4 command-line bash

我正在编写一个简单的桌面启动脚本,它等待磁盘空闲,然后使用 启动下一个外部程序(如 Firefox、Skype 或conky&,例如:

ps cax | grep conky > /dev/null
if [ $? -eq 0 ]; then
  echo "Conky is already running."
else
  wait-for-disk-idle sda
  conky &
fi
Run Code Online (Sandbox Code Playgroud)

这很容易。

问题是一些程序向终端发送了大量调试输出,这些输出与我的初始化脚本产生的消息混合在一起。

问题: 有没有办法异步启动外部程序,使其标准输出被丢弃?

我已经尝试过的:

  • conky & >/dev/null 2>/dev/null
  • bash -c conky &

正确答案:

bash -c "conky >/dev/null 2>/dev/null &"
Run Code Online (Sandbox Code Playgroud)

tdk*_*2fe 6

您可能还想丢弃任何 STDERR 输出。你可以这样做:

conky > /dev/null 2>&1 &

该语句实质上告诉 shell 执行以下操作:

  1. conky > /dev/null - 将所有标准输出重定向到 /dev/null
  2. 2>&1- 将标准错误重定向到标准输出当前指向的位置。由于之前的重定向,您的标准输出指向 /dev/null,因此会出现标准错误。
  3. & - 在子外壳(背景)中运行它。
  4. 感谢@alexis 指出我的描述&不够准确:

    (a) 每个外部命令都必须在 (v) fork 之后运行,而不仅仅是后台进程。(b) 后台进程不在子 shell 中运行,而是在 fork 之后立即执行。当进程处于后台时,真正的区别在于调用 shell 不会立即 wait(2) 等待它(而是打印提示并等待用户输入)。

重定向输出时,Bash 按顺序从左到右读取重定向。Bash 还把 '&'当作命令分隔符,它可以在任何地方使用 ';' 通常会被使用。你正在做的是告诉 bash

  1. 在后台运行 conky。更具体地说, fork 进程并在子 shell 中异步运行它,并将终端的控制权返回给用户。
  2. Bash 认为这是一个新命令- 这与>/dev/null在提示符下运行相同,重定向之前没有任何内容。没发生什么事。
  3. 将标准错误从不存在的命令重定向到 /dev/null。