我正在尝试在我的 unRAID 服务器上运行 Minecraft 服务器。
服务器将在 shell 中运行,然后等待输入。要停止它,我需要输入“stop”并按 Enter 键,然后它将拯救世界并优雅地退出,然后我又回到 shell 中。如果我通过 telnet 进入 NAS 盒子来运行它,那么一切都有效,但我想直接在盒子上运行它。
这是我之前的第一次尝试:
#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 是我拥有 Craftbukkit.jar 和所有世界文件等的文件夹。如果我直接输入该屏幕行,屏幕会分离设置并启动服务器。如果我从脚本中执行该行,它似乎没有设置屏幕
要停止服务器,我需要“键入”STOP,然后按 Enter。我的方法是
screen -S minecraft -X stuff "stop $(echo -ne '\r')"
将文本停止和回车发送到屏幕“minecraft”。但这不起作用,即使我直接在命令行上输入它。但是,如果我“screen -r”,我可以进入服务器正在运行的屏幕,然后输入“stop”,它就会正确关闭。
如果我远程登录并手动执行,服务器运行良好,只需要在不从远程计算机连接的情况下运行它。
答案1
我至少可以解决部分问题:为什么该stop
部分不起作用。实验上,当您以分离模式 ( ) 启动 Screen 会话时screen -d -m
,不会选择任何窗口,因此稍后发送的输入screen -X stuff
会丢失。您需要明确指定要将击键发送到窗口 0 ( -p 0
)。无论如何,这是一个好主意,以防您出于某种原因在该 Screen 会话中碰巧创建其他窗口。
screen -S minecraft -p 0 -X stuff "stop^M"
(屏幕翻译^M
为 control-M,这是按键发送的字符Enter。)
从脚本启动会话的问题可能与 unMENU 有关。
答案2
首先,关于轻松输入换行符的说明:
请注意,该$()
构造会从命令的输出中删除换行符,以便输出行可以用作其他程序的参数。这可能会导致意外的行为。在这种情况下,我假设您专门尝试发送相当于Enter击键的内容。虽然您发送的回车符\r
不会被条纹化,但有几种更简单的方法可以输入该字符,而无需额外的命令。
您可以在双引号内放置常规换行符
screen -S minecraft -X stuff "stop "
Ctrl或者您可以使用+序列在终端行中输入字符v Enter。这看起来像
^M
在终端中,但它是一个特殊的换行符。screen -S minecraft -X stuff "stop^M"
其次,关于不稳定的屏幕行为的说明。 (Gilles的解释和解决方案)
Screen 在接受从未附加的屏幕会话输入时出现问题。如果你运行它,它将失败:
screen -d -m -S minecraft zsh
screen -S minecraft -X stuff "stop^M"
screen -r minecraft
但如果你运行这个它将起作用:
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
最后,您可以使用表现更好的方法tmux
来代替screen
.
GNU-Screen 一直是事实上的终端多路复用器已经使用了很多年,但它早已停止开发,错误和怪癖也没有得到修复。 Tmux 正在积极开发中,包括许多屏幕无法触摸的功能,并且其开箱即用的行为更加直观。而且,它有更好的记录。以下是转换代码的方法:
# Start new detached 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"
答案3
我为挖掘这篇旧文章而道歉,但是如果在我遇到类似问题时可以使用此信息,这将对我的努力有所帮助。关于如何在 bash 脚本中发送屏幕命令有很多问题。就像剥猫皮一样,这可以完成,但我喜欢这种方式。有了这个,您只需调用 say_this 函数就可以发送任何命令或说出任何内容。
#!/bin/bash
say_this()
{
screen -S minecraft -p 0 -X stuff "$1^M"
}
say_this "say Saving world"
say_this "save-off"
say_this "save-all"
...
这是用ssh!
#!/bin/bash
say_this()
{
# Dont forget to set NAME or whatever
ssh -p 8989 192.168.1.101 screen -S $NAME -p 0 -X stuff \"$1^M\"
}
say_this "say test"
say_this "say !@#$%^&*()<>?This string will work!"