4

I'm writing a simple desktop initiation script which waits for disk idle, and then launches next external program (like Firefox, Skype or conky) using &, like:

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

That's easy.

The problem is that some programs spew a lot of debug output to the terminal, which gets mixed with the messages produced by my initialization script.

The question: Is there any way to asynchronously launch an external program so that its standard output is discarded?

What I already tried:

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

The correct answer:

bash -c "conky >/dev/null 2>/dev/null &"
5
  • If this isn't intentionally inefficient, note that you're breaking the concept of "multi-tasking" here. It's also no guarantee that more than one process won't end up vying for I/O anyway.
    – goldilocks
    Commented Jan 19, 2014 at 8:51
  • @goldilocks Non-ssd hard drives don't handle concurrent I/O requests efficiently, so in practice, you don't have true multitasking for I/O-intensive tasks on average non-ssd notebook anyway. Commented Jan 19, 2014 at 8:56
  • It doesn't matter what form the storage is in; multi-tasking is achieved at the OS level, not the device level. Whether or not the device deals (well) with concurrent requests is another issue, and it's naive to believe that simply forking processes into the background and waiting for (whatever criteria constitutes) disk inactivity will mean that there won't end up being concurrent requests anyway. I'm loaded from disk, I partially initialize -- leaving the disk "inactive" -- another process starts...now I need something else from disk...nothing has changed except you've introduced a delay.
    – goldilocks
    Commented Jan 19, 2014 at 14:00
  • @goldilocks Well, in principle you are right: I agree, that in the ideal world this sort of optimization is a task for kernel. But in reality initializing apps in serial is faster than in parallel + you get bonus of better overall responsiveness of the system at that time. Do you have any alternate method for speeding up the initialization tasks? Commented Jan 19, 2014 at 21:27
  • I can't agree that initializing in serial "is faster in reality", although we'd have to set up some tests to confirm this, so I'll just leave that as my opinion -- but note as an analogy the use of parallelism in newer init systems (systemd and upstart supplanting the traditionally serial sysV). However, reducing the speed/efficiency of initialization this way will give you the "bonus of better overall responsiveness of the system at that time", which is why I asked at first (sincerely), "If this isn't intentionally" so. If you appreciate the net effect, go with it!
    – goldilocks
    Commented Jan 19, 2014 at 21:37

2 Answers 2

6

You probably want to discard any STDERR output as well. You can do both like so:

conky > /dev/null 2>&1 &

This statement essentially tells the shell to do the following:

  1. conky > /dev/null - redirect all standard output to /dev/null
  2. 2>&1 - Redirect standard error to where standard output is currently pointing. Because of the previous redirect, you standard output is pointing to /dev/null, so standard error will follow.
  3. & - Run this in a sub-shell (background).
  4. Thanks to @alexis for pointing out that my description for & wasn't quite precise:

    (a) Every external command must be run after a (v)fork, not just background processes. (b) Backgrounded processes are not run in a sub-shell, but executed immediately after the fork. The real difference when a process is backgrounded is that the invoking shell doesn't immediately wait(2) for it (but prints a prompt and awaits user input).

When redirecting output, Bash reads the redirects in order, from left to right. Bash also treats the '&' as a command separator, which can be used anywhere ';' would normally be used. What you were doing was telling bash

  1. Run conky in the background. More specifically, fork the process and run it in a sub-shell, asynchronously, and return control of the terminal to the user.
  2. Bash considers this a new command - this is the same as running >/dev/null on the prompt with nothing preceding the redirect. Nothing happens.
  3. Redirect the standard error to /dev/null from the nonexistent command.
4
  • Well I thought that I knew that. I guess I must have mistaken 2> with >2... Commented Jan 19, 2014 at 9:00
  • But still: this conky > /dev/null 2>&1 & still produces a PID of spawn process as output (e.g. [1] 2753). Is there any way to get rid of that too? Commented Jan 19, 2014 at 9:01
  • Never mind, I've an answer: bash -c "conky >/dev/null 2>/dev/null &" Commented Jan 19, 2014 at 9:04
  • 1
    @tdk, your description of & isn't quite accurate: (a) Every external command must be run after a (v)fork, not just background processes. (b) Backgrounded processes are not run in a sub-shell, but executed immediately after the fork. The real difference when a process is backgrounded is that the invoking shell doesn't immediately wait(2) for it (but prints a prompt and awaits user input).
    – alexis
    Commented Jan 19, 2014 at 14:58
2

Instead of

conky & >/dev/null 2>/dev/null

Use:

conky >/dev/null 2>/dev/null &

Explanation: Because '&' serves as a statement separator, the former is really two commands. It works like this:

conky &
>/dev/null 2>/dev/null

The first command runs conky in the background but does not redirect its output. The second redirects the output on a nonexistent command. To redirect conky's output, you need to run:

conky >/dev/null 2>/dev/null

To redirect conky's output and also run conky in the background, use:

conky >/dev/null 2>/dev/null &
2
  • Oh, that is a good answer. Thank you! The command conky >/dev/null 2>/dev/null & still produces a PID of the spawned process to the terminall (e.g. [1] 2574). Is there any chance to get rid of that as well? Commented Jan 19, 2014 at 9:02
  • To answer my own question, I think I've found one: bash -c "conky >/dev/null 2>/dev/null &" Commented Jan 19, 2014 at 9:04

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .