0

I have a Minecraft Server on a Raspberry Pi 4 that I would like to run in the background. Is there a proper way for me to do this? I hear there are other methods, such as ctrl-z, '&', etc.

Which method is the best approach?

  • 1
    Do you want it to start up as a system service when the Pi boots? Or would you prefer to manually launch it, but have it run in the background? – Tim Campbell Jul 30 at 3:57
  • @TimCampbell Manually launch it with a command: "./directory/to/script.sh". But somehow, make some modifications for a proper background run. Also in part because I may want to reconnect to the same background task later on and then make background again. – Macintosh Fan Jul 30 at 4:03
4

As with nearly all things Unix/Linux, there is more than one solution.

You mentioned you want to be able to launch your server as a foreground process but be able to send it to the background and ... recall it to the foreground at a later time. I'll address answers to those questions here. There is a completely different way of doing things if you want to set up your process so that it launches as a system service (e.g. launching it at boot time). If you regularly know that this is what you want, it is the more accepted (e.g. more operationally mature) way of doing things. I wont address that method here -- you indicated this is not what you want to do.

How to run jobs in the background -- the simple way

The easy way to run any job in the background is to put an & at the end of the line in the command shell when launching the process.

e.g.

$ /directory/to/script.sh &

This presume you know that you want to run this in the background when you launching it.

The command shell (terminal window) will issue a job id (in square brackets), followed by the process ID.

I don't have a minecraft server, so I'll simulate running a job in the background using a 'sleep' command (you would use your minecraft script instead of the sleep command):

pi@tims-raspi-8gb:~ $ sleep 60 &
[1] 3958

This starts the job running in the background and note that it was assigned job ID 1 (because it is the first job launched in this command shell) and the process ID was 3958.

When the job finishes the run, it will produce this output (typically the next time you hit the enter key you'll see the message):

pi@tims-raspi-8gb:~ $ 
[1]+  Done                    sleep 60

Moving foreground jobs to the background

If you launched the job in the foreground but want to move it to the background, you have to interrupt the job using ^ Control+Z.

pi@tims-raspi-8gb:~ $ sleep 60
^Z
[1]+  Stopped                 sleep 60

This stops the job and returns your command prompt. At this point the job is stopped and neither in the foreground or background. But it is not terminated.

To move it to the background, type:

$ bg

e.g.

pi@tims-raspi-8gb:~ $ bg
[1]+ sleep 60 &

This moves the currently stopped job to continue running in the background.

View the list of background jobs

If you've launched a few jobs and can't remember which job ID is associated with each of them, you can list them by using the jobs command.

pi@tims-raspi-8gb:~ $ jobs
[1]+  Running                 sleep 60 &

In this example, only one job was running. But if multiple jobs were running you would have seen each listed with their job ID (note that this does not display their process ID).

Recalling a background job to the foreground

To return the job to the foreground, use fg %

pi@tims-raspi-8gb:~ $ fg %1
sleep 60

This brings the task back to the foreground. You can always use ^ Control+Z to stop it and then use bg to return it to the background again.

What happens to job output?

When you run a program in the foreground, any output from that process is typically displayed in your terminal window. So what happens to background processes?

In Unix & Linux, programs normally receive input from stdin (standard input) and send output to stdout (standard output) with the exception of error messages, which are typically sent to stderr (standard error).

By default, stdin is mapped to the terminal keyboard, stdout is mapped to the terminal display, and stderr is also mapped to the terminal display. But you can override those.

If you do not override those, you may see messages from background jobs popping up on your terminal display (in the midst of other things you may be doing) and this can get annoying.

To avoid this, you can redirect the output using the redirect symbol: >

I have a simple script named sayhello.sh with the following:

#!/bin/bash

sleep 10
echo "Hello"

If I simply run this in the background via ./sayhello.sh & then the word "Hello" will pop up on the terminal in 10 seconds... in the midst of whatever else I might be doing. To redirect this to an output file (to avoid the message from popping up on my display) I can use the redirect >.

./sayhello.sh > sayhello.log &

This will run the job in the background, but send the output to sayhello.log instead of the terminal display.

That only redirects stdout ... not stderr ... so error messages thrown may still be displayed on the terminal (and... maybe that's what you want so you can be immediately aware of an errors). But often even stderr should be redirected.

It turns out that both stdout and stderr are mapped to numeric values 1 and 2 respectively. So:

./sayhello.sh 1> sayhello.log

is actually the same as

./sayhello.sh > sayhello.log

The notation 1> is the same as just using > alone, but it is a bit more obvious (due to the number 1 that we are specifically referring to stdout).

The notation 2> means you want to redirect stderr. I could use

./sayhello.sh 1> sayhello.log 2> sayhello-errors.log 

This sends stdout to sayhello.log and stderr to sayhello-errors.log.

If you want both stdout and stderr to go to the same file, there's a short-hand notation:

./sayhello.sh > sayhello.log 2>&1 

The first redirect via > says you want to redirect stdout. The second redirect is a bit more complicated 2>&1 which, translated to english says "2 goes to the same place as 1" or... in even more plain english "send my error messages to the same place where I am logging standard output."

Overwritting vs. appending ... or just getting rid of output completely

The redirect directive > normally creates the file and begins writing output to it. But if the file already exists, the directive overwrites the file. Any previous contents (from prior runs) are lost.

You can use the concatenate notation >> to append to the existing file. This will not overwrite the file:

./sayhello.sh >> sayhello.log 2&1> &

This runs the job in the background but appends output to sayhello.log (if the file already exists... otherwise it will create a new file) and sends stderr to that same file.

If you don't want the output, there is a special file in Unix/Linus named /dev/null. This sends the output to the great bit-bucket in the sky (information is simply discarded.) It's like sending the output to the trash.

./sayhello.sh > /dev/null 2>&1 

The process will run... but will not produce any output (at least not output from stdout or stderr. Other I/O are not impacted by this.

More help

There are other short-hand notations as well. I also didn't go into how to remap stdin (via <) nor how to pipe the stdout of one process to the stdin of another process (via |).

All of these (bg, fg, jobs, &, >, etc.) are internal shell commands. They don't have their own documentation. You'll find the documentation embedded in the documentation for your command shell (which, by default, is the BASH shell). This means you can use man bash to read the built-in Linux documentation. To confirm, type echo $SHELL ($SHELL is an environment variable that defines the name of the currently running shell process.) It will likely say:

pi@tims-raspi-8gb:~ $ echo $SHELL
/bin/bash

Then use man bash to read the manual page.

| improve this answer | |
  • I ran the process in the background, but what is weird is that it doesn't show the background processes, even if I type "jobs". And if I try to type: "fg %1" or "fg 1", it says there is no such job. – Macintosh Fan Jul 30 at 19:19
  • 1
    Does your shell script kick-off launch a background process and then terminate? The process for using & will cause a foreground job to run in the background. But there are start-scripts that only launch a background process but the foreground script itself does not keep running. – Tim Campbell Jul 30 at 19:24
  • It doesn't terminate the process, but I just can't seem to bring it back to the foreground. I also tried '&' before and that also prevents me from bringing it to the foreground. – Macintosh Fan Jul 30 at 19:26
  • The issue I’m facing may be too complex to solve. – Macintosh Fan Jul 30 at 23:22
  • 1
    Probably not complex... but it might help to see your script to see what it's doing. The script may have been developed with the intention that it starts a background job. If you run the script, but do not type an & at the end, does it return a new shell prompt after you launch it... or does the shell prompt not return until you shut it down? – Tim Campbell Jul 31 at 0:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.