11

Specifically, I want to run

lsyncd lsyncd.lua

And

webpack --progress --color -w

Which are both long-running processes. I want to see the output from both, interlaced in my terminal. It doesn't matter if the results are a bit jumbled, I just like to see that they're doing what they're supposed to.

Also, I want it to kill both processes when I press Ctrl+C.


I'm trying

parallel ::: 'lsyncd lsyncd.lua' 'webpack --progress --color -w'

which seems to be working, but I can't see any output even though when I run those commands individually, they output something.

3

6 Answers 6

8

GNU Parallel defaults to postponing output until the job is finished. You can instead ask it to print output as soon there is a full line.

parallel  --lb ::: 'lsyncd lsyncd.lua' 'webpack --progress --color -w'

It avoids half-line mixing of the output:

parallel -j0 --lb 'echo {};echo -n {};sleep {};echo {}' ::: 1 3 2 4

Spend 20 minutes reading chapter 1+2 of GNU Parallel 2018 (online, printed). Your command line will love you for it.

2
  • 1
    Will these prepend lines of output with labels allowing you to distinguish output lines from the two commands? If not, is there an option to do so? And will it preserve colors?
    – Anomaly
    Oct 1, 2021 at 18:02
  • @Anomaly --tag/--tagstring/--ctag/--ctagstring will prepend the lines of each job. Colors is really the job of the program: parallel --tag ls --color ::: /bin /usr
    – Ole Tange
    Oct 1, 2021 at 18:09
6

Using parallel (in the moreutils package):

parallel -j 2 -- 'lsyncd lsyncd.lua' 'webpack --progress --color -w'

Since the parallel process runs in the foreground, hitting CTRL+C will terminate all the processes running on top of it at once.

  • -j: Use to limit the number of jobs that are run at the same time;
  • --: separates the options from the commands.
% parallel -j 2 -- 'while true; do echo foo; sleep 1; done' 'while true; do echo bar; sleep 1; done'
bar
foo
bar
foo
bar
foo
^C
%
1
  • 2
    Aha. That parallel seems to be different from than the parallel package (GNU?). This one seems to work! The other one just kept saying "parallel: Warning: Input is read from the terminal. Only experts do this on purpose. Press CTRL-D to exit.".
    – mpen
    Dec 18, 2015 at 16:52
2

& to the rescue. It launches the two processes in parallel.

lsyncd lsyncd.lua & webpack --progress --color -w

This will do the trick.

Didn't read the kill part. A ctrl+C here would only terminate the second one. The process preceding the & runs in the background although it outputs on the stdout.

The shortest way to terminate both processes is: 1. Type Ctrl+C once. It kills the foreground process. 2. Type fg and type Ctrl+C again. It brings the background process to foreground and kills it too.

HTH!

9
  • Derp. So simple. That looks to be doing exactly what I want. Thank you!
    – mpen
    Dec 17, 2015 at 18:53
  • True. But you cannot stop the first process with Ctrl-C unless you bring it to the foreground.
    – nobody
    Dec 17, 2015 at 18:53
  • @nobody actually you can stop the second one because it's running in foreground. Updated the answer.
    – Donbhupi
    Dec 17, 2015 at 18:55
  • Oh poop. I want them both to die. Need to keep this simple so it's easy to start and stop for the linux noob.
    – mpen
    Dec 17, 2015 at 18:55
  • @mpen can't think of an easy way to kill the process in background. Either use the jobs thing in the other answer or run ps -a in the shell, that will tell the pid that you can kill manually.
    – Donbhupi
    Dec 17, 2015 at 18:57
2

Using GNU parallel

1. Output ordered by finishing time of each command

You could group your parallel executed commands by using parallel (install it with sudo apt install gnu_parallel) with the argument --group. This ensures, that the output of each command waits till the command has finished (avoids mixed output).

Example:

parallel --group 'echo -n {};sleep {};echo {}' ::: 1 3 2 4

Output:

11
22
33
44

From the manual (man parallel):

--group: Group output. Output from each job is grouped together and is 
only printed when the command is finished.

2. Output ordered by the order of input parameters

Another option is to control the output by the order of input parameters by using the -k argument.

Example:

parallel -k 'echo -n {};sleep {};echo {}' ::: 1 3 2 4

Output:

11
33
22
44

From the manual (man parallel):

--keep-order, -k: Keep sequence of output same as the order of input. 
Normally the output of a job will be printed as soon as the job completes.
1

You have more options. Run the first command and press Ctrl-Z. This puts the command to wait in the background. Now type bg and it will run in background. Now run the second command and press Ctrl-Z again. Type bg again and both programs will run in background.

Now you can type jobs and it will print which commands are running in background. Type fg <job number> to put program in foreground again. If you omit the job number it will put the last job in the foreground. When the job is in foreground you can stop it with Ctrl-C. I don't know how you would stop both with one Ctrl-C.

You can also add & at the end which puts it running in the background immediately without Ctrl-Z and bg. You can still bring it in foreground with fg.

1

There is a light-weight way of doing it without installing anyting.

Step 1: Create a script file runner.sh

#!/bin/bash
lsyncd lsyncd.lua &
P1=$!
webpack --progress --color -w &
P2=$!
wait $P1 $P2

Step 2: Make it executable

chmod +x runner.sh

Step 3: Run it

./runner.sh

It works like cream

Explanation:

  1. some_command & means run some_command and put it in background
  2. lsyncd lsyncd.lua & means run lsyncd lsyncd.lua and put this process in background.

Note: this works with Debian based Linux distros like Ubuntu

You must log in to answer this question.

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