Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I'm trying to run a minecraft server on my unRAID server.

The server will run in the shell, and then sit there waiting for input. To stop it, I need to type 'stop' and press enter, and then it'll save the world and gracefully exit, and I'm back in the shell. That all works if I run it via telnetting into the NAS box, but I want to run it directly on the box.

this is what I previously had as a first attempt:

#define USER_SCRIPT_LABEL Start Minecraft server
#define USER_SCRIPT_DESCR Start minecraft server. needs sde2 mounted first
cd /mnt/disk/sde2/MCunraid
screen -d -m -S minecraft /usr/lib/java/bin/java -Xincgc -Xmx1024M -jar CraftBukkit.jar

MCunraid is the folder where I have the Craftbukkit.jar and all the world files etc. If I type that screen line in directly, the screen does setup detached and the server launches. If I execute that line from within the script it doesn't seem to set up a screen

for stopping the server, I need to 'type' in STOP and then press enter. My approach was

screen -S minecraft -X stuff "stop $(echo -ne '\r')"

to send to screen 'minecraft' the text s-t-o-p and a carriage return. But that doesn't work, even if I type it directly onto the command line. But if I 'screen -r' I can get to the screen with the server running, then type 'stop' and it shuts down properly.

any guidance here? As far as I can tell (linux noob), the command formatting is ok, but the screen doesn't seem to be hearing me. The server runs well if I telnet in and do it manually, just need to run it without being connected from my remote computer.

share|improve this question
    
This looks right. What's the full content of the script and how are you running it? Does it produce any output? How do you tell that screen failed to start? Try adding set -x at the top of the script (just after the #! line) and report the trace output when you run the script. –  Gilles May 28 '11 at 13:05
    
that is the full content of the script :) the screen command works if I type it in directly, so I think my main issue is the stop part –  richard plumb May 28 '11 at 13:23
    
You wrote “If I execute that line from within the script it doesn't seem to set up a screen”. So does the start part work or not? If it doesn't, see my first comment. –  Gilles May 28 '11 at 13:53
    
I'm trying to run it as an unMENU user script. If I have the user script with that exact screen command, nothing happens. If I type the screen command into a telnet window, it launches the server in a screen like you'd expect. So I think there is some difference I don't understand in the way unMENU user scripts are handled. –  richard plumb May 28 '11 at 14:02
    
Now we're getting somewhere. Please update your question with information on how you're using unMENU. And do try adding two lines #!/bin/bash and set -x at the top of the script, and show us the trace output from the script. You might need to look in the unMENU documentation to find out where that output goes. –  Gilles May 28 '11 at 14:05

3 Answers 3

up vote 17 down vote accepted

I can solve at least part of the problem: why the stop part isn't working. Experimentally, when you start a Screen session in detached mode (screen -d -m), no window is selected, so input later sent with screen -X stuff is just lost. You need to explicitly specify that you want to send the keystrokes to window 0 (-p 0). This is a good idea anyway, in case you happen to create other windows in that Screen session for whatever reason.

screen -S minecraft -p 0 -X stuff "stop$(printf \\r)"

(printf \\r is a more portable way of writing echo -ne '\r', the echo variant doesn't work in e.g. dash which is /bin/sh on Ubuntu.)

The problem with starting the session from a script is likely related to unMENU.

share|improve this answer
    
beautiful, works great (at least from the command line, will poke the unmenu guys later). This seems to have thrown quite a few people and its the first time I've seen a concrete solution. I just wish I had enough points to vote you up :D –  richard plumb May 28 '11 at 15:11
    
Damn s**t ! It works even screen is already attached, without reattaching it ! What's a great way to send commands to simple apps from other apps in system. Thanks! :) –  Grzegorz Wierzowiecki Nov 29 '11 at 9:54
    
I never had this problem, probably because I always planned to have several (named) windows in my screen session, and I always choose window by name. –  Ekevoo Jan 8 at 13:48

First, a note on easily entering newlines:

Just a heads up that the $() construct strips newlines from the output of command so that the output lines can be used as the arguments for other programs. This can cause unexpected behavior. In this case I assume you are specifically trying to send the equivolant of Enter keystroke. While the carriage return you are sending with \r won't get striped, there are several easier ways to enter that character without the need for the extra command.

  1. You can place a regular newline inside your double quotes

    screen -S minecraft -X stuff "stop "

  2. Or you can enter the character in a terminal line using the Ctrl+v Enter sequence. This will look something like ^M in the terminal, but it's a special newline character.

    screen -S minecraft -X stuff "stop^M"

Secondly, A note on erratic screen behavior. (Explanation and solution by Gilles)

Screen has an issue with accepting input to a screen session that has never been attatched. If you run this it will have failed:

screen -d -m -S minecraft zsh
screen -S minecraft -X stuff "stop^M"
screen -r minecraft

But if you run this it will work:

screen -d -m -S minecraft zsh
screen -r minecraft (then disconnect with Ctrl-a-d)
screen -S minecraft -X stuff "stop^M"
screen -r minecraft

Lastly, you could use the much better behaved tmux instead of screen.

GNU-Screen has been a defacto terminal multiplexer for many years, but it has long ceased to be developed and bugs and quirks aren't getting fixed. Tmux is under active development, includes many features that screen can't touch, and it's behavior out of the box is rather more intuitive. Also, it's better documented. Here's how you would convert your code:

# Start new detatched tmux session with a named window pane running the java app
tmux new-session -d -n minecraft /usr/lib/java/bin/java [args]

# Send it keys to stop the mincraft server
tmux send-keys -t minecraft "stop^M"
share|improve this answer
    
if I manually switch over using screen -r, I can see the screen, and there is no text entered at all. even if the carriage return was failing, I should still get 'stop' typed in. But nothing –  richard plumb May 28 '11 at 13:24
    
if I have a script with screen -r on one line, and then screen -X stuff "stop^M" then it does stop the server, but also complains with 'error uknown option r' –  richard plumb May 28 '11 at 13:36
    
I tested in here by creating screen session, then using the command above and it works perfectly. Are you able to connect to your screen session using screen -d -RR minecraft? –  Caleb May 28 '11 at 13:38
    
yes, that connects me to the screen. so does screen -r.. hang on, if I try screen -S minecraft -X stuff "stop^M" then manually screen -r, there is 'stop' text in the screen. –  richard plumb May 28 '11 at 13:39
    
Works for me. Perhaps you have something funky in your .screenrc or you have a bunch of defunkt screen sessions open with that name and so you are sending data to the wrong one? screen -list? –  Caleb May 28 '11 at 13:42

I figured I'd share my Minecraft server's control script since it may be useful to the OP and others.

Caveats: this script "works on my machine" and comes with no warranty, support, etc.

This script goes in the /etc/init.d directory (at least on Ubuntu server 10.04) and is invoked like this (assuming you name the script 'minecraftd':

#Start the server
sudo /etc/init.d/minecraftd start
#Stop the server
sudo /etc/init.d/minecraftd stop
#Create a backup of the world
sudo /etc/init.d/minecraftd backup
#Restart the server
sudo /etc/init.d/minecraftd restart
#Use the console "say" command (Quotes are important)
sudo /etc/init.d/minecraftd mcsay "Hello, world!"
#Issue direct commands to the server console (i.e. "ban bobby21")
sudo /etc/init.d/minecraftd mcdo "ban bobby21"
#Query the server status (running/not running)
sudo /etc/init.d/minecraftd status
share|improve this answer
    
looks good, fairly simple to update for a noob like me I think? I'll be running this headless with buttons to start/stop but I think a 'backup' button would be good, and then other commands like ban etc I could do via telnet session if needed (less common). –  richard plumb May 30 '11 at 8:18
    
also, do you think this would be able to run craftbukkit by changing the SERVICE command? –  richard plumb May 30 '11 at 8:27
    
@richard plumb Yeah, all you should have to do is change the SERVICE variable at the top to use CraftBukkit or any other mod. –  Andrew Lambert May 31 '11 at 2:00

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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