enviando entrada de texto para uma tela separada

40

Estou tentando executar um servidor de minecraft no meu servidor unRAID.

O servidor será executado no shell e ficará aguardando a entrada. Para pará-lo, eu preciso digitar 'stop' e pressionar enter, e então ele salvará o mundo e sairá com elegância, e eu estou de volta ao shell. Isso tudo funciona se eu o executar via telnet na caixa NAS, mas quero executá-lo diretamente na caixa.

isto é o que eu tive anteriormente como primeira tentativa:

#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

O MCunraid é a pasta onde eu tenho o Craftbukkit.jar e todos os arquivos do mundo, etc. Se eu digitar essa linha de tela diretamente, a tela será desmarcada e o servidor será iniciado. Se eu executar essa linha de dentro do script, não parece configurar uma tela

para parar o servidor, eu preciso digitar em STOP e depois pressionar enter. Minha abordagem foi

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

para enviar para a tela 'minecraft' o texto s-t-o-p e um retorno de carro. Mas isso não funciona, mesmo se eu digitá-lo diretamente na linha de comando. Mas se eu 'screen -r' eu posso chegar na tela com o servidor rodando, então digite 'stop' e ele desliga corretamente.

O servidor funciona bem se eu fizer o telnet e fizer isso manualmente, só preciso executá-lo sem estar conectado a partir do meu computador remoto.

    
por richard plumb 28.05.2011 / 14:52

4 respostas

35

Eu posso resolver pelo menos parte do problema: por que a parte stop não está funcionando. Experimentalmente, quando você inicia uma sessão de Tela no modo desanexado ( screen -d -m ), nenhuma janela é selecionada, portanto, a entrada posteriormente enviada com screen -X stuff é perdida. Você precisa especificar explicitamente que deseja enviar as combinações de teclas para a janela 0 ( -p 0 ). Esta é uma boa idéia, de qualquer forma, caso você crie outras janelas nessa sessão de tela por qualquer motivo.

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

(A tela traduz ^M para control-M, que é o caractere enviado pela tecla Enter .

O problema de iniciar a sessão a partir de um script provavelmente está relacionado ao unMENU.

    
por 28.05.2011 / 16:37
22

Primeiro, uma nota sobre como inserir novas linhas facilmente:

Apenas um aviso que a construção $() retira as novas linhas da saída do comando, para que as linhas de saída possam ser usadas como argumentos para outros programas. Isso pode causar um comportamento inesperado. Neste caso eu suponho que você está especificamente tentando enviar o equivalente de Enter keystroke. Embora o retorno de carro que você está enviando com \r não seja distribuído, há várias maneiras mais fáceis de inserir esse caractere sem a necessidade do comando extra.

  1. Você pode colocar uma nova linha regular dentro de suas aspas duplas

    screen -S minecraft -X stuff "stop
    "
    
  2. Ou você pode inserir o caractere em uma linha terminal usando a seqüência Ctrl + v Enter . Isso será parecido com ^M no terminal, mas é um caractere de nova linha especial.

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

Em segundo lugar, uma observação sobre o comportamento errático da tela. ( Explicação e solução de Gilles )

A tela tem um problema ao aceitar entrada para uma sessão de tela que nunca foi anexada. Se você executar isso, ele terá falhado:

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

Mas se você executar isso, funcionará:

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

Por último, você poderia usar o muito melhor comportado tmux em vez de screen .

O GNU-Screen tem sido um multiplexador de terminais de fato por muitos anos, mas há muito tempo deixou de ser desenvolvido e os bugs e peculiaridades não estão sendo consertados. O Tmux está em desenvolvimento ativo, inclui muitos recursos que a tela não pode tocar e seu comportamento pronto para uso é bastante mais intuitivo. Além disso, é melhor documentado. Veja como você converteria seu código:

# 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"
    
por 28.05.2011 / 14:59
4

Peço desculpas por desenterrar este post antigo, mas isso teria me ajudado em meus esforços se essas informações estivessem disponíveis no momento em que eu tive um problema semelhante. Há muitas perguntas sobre como enviar comandos de tela em um script bash. Tal como acontece com a pele do gato isso pode ser feito, mas eu gosto desse jeito. Com isso, você pode enviar qualquer comando ou dizer qualquer coisa apenas chamando a função 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"
...

Isso é com 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!"
    
por 26.12.2014 / 17:13
3

Pensei em compartilhar o script de controle do meu servidor Minecraft , pois ele pode ser útil para o OP e outros.

Advertências: este script "funciona na minha máquina" e não tem garantia, suporte etc.

Este script vai no diretório /etc/init.d (pelo menos no servidor Ubuntu 10.04) e é chamado assim (supondo que você nomeie o 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
    
por 29.05.2011 / 01:31