invio di input di testo a uno schermo separato


44

Sto cercando di eseguire un server Minecraft sul mio server unRAID.

Il server verrà eseguito nella shell, quindi siederà lì in attesa di input. Per fermarlo, devo digitare 'stop' e premere invio, quindi salverà il mondo e uscirà con grazia, e sono tornato nella shell. Funziona tutto se lo eseguo tramite telnetting nella casella NAS, ma voglio eseguirlo direttamente sulla casella.

questo è quello che ho avuto in precedenza come primo tentativo:

#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 è la cartella in cui ho Craftbukkit.jar e tutti i file del mondo, ecc. Se scrivo direttamente quella linea di schermo, lo schermo si configura e il server si avvia. Se eseguo quella riga all'interno dello script, non sembra impostare uno schermo

per arrestare il server, devo "digitare" in STOP e quindi premere invio. Il mio approccio è stato

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

per inviare allo schermo 'minecraft' la fermata del testo e un ritorno a capo. Ma non funziona, anche se lo scrivo direttamente sulla riga di comando. Ma se 'screen -r' posso arrivare allo schermo con il server in esecuzione, quindi digitare 'stop' e si spegne correttamente.

Il server funziona bene se telnet in e lo faccio manualmente, ho solo bisogno di eseguirlo senza essere collegato dal mio computer remoto.


Questo sembra giusto . Qual è il contenuto completo dello script e come lo stai eseguendo? Produce qualche output? Come si dice che screennon è stato avviato? Prova ad aggiungere set -xnella parte superiore dello script (subito dopo la #!riga) e segnala l'output di traccia quando esegui lo script.
Gilles 'SO- smetti di essere malvagio'

questo è l'intero contenuto dello script :) il comando screen funziona se lo digito direttamente, quindi penso che il mio problema principale sia la parte di arresto
richard plumb

Hai scritto "Se eseguo quella riga all'interno dello script non sembra impostare uno schermo". Quindi la parte iniziale funziona o no? In caso contrario, vedi il mio primo commento.
Gilles 'SO- smetti di essere malvagio'

Sto cercando di eseguirlo come uno script utente unMENU. Se ho lo script utente con quel comando esatto sullo schermo, non succede nulla. Se digito il comando screen in una finestra telnet, avvia il server in una schermata come ti aspetteresti. Quindi penso che ci sia qualche differenza che non capisco nel modo in cui vengono gestiti gli script utente di unMENU.
Richard Plumb,

Ora stiamo arrivando da qualche parte. Aggiorna la tua domanda con informazioni su come stai utilizzando unMENU. E prova ad aggiungere due righe #!/bin/bashe set -xnella parte superiore dello script e mostraci l'output di traccia dallo script. Potrebbe essere necessario consultare la documentazione di unMENU per scoprire dove va l'output.
Gilles 'SO- smetti di essere malvagio'

Risposte:


40

Posso risolvere almeno una parte del problema: perché la stopparte non funziona. Sperimentalmente, quando si avvia una sessione dello schermo in modalità staccata ( screen -d -m), non viene selezionata alcuna finestra, quindi l'input inviato successivamente screen -X stuffviene perso. È necessario specificare esplicitamente che si desidera inviare i tasti alla finestra 0 ( -p 0). Questa è comunque una buona idea, nel caso in cui ti capiti di creare altre finestre in quella sessione dello schermo per qualunque motivo.

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

(Lo schermo si traduce ^Min control-M, che è il carattere inviato dal Entertasto.)

Il problema con l'avvio della sessione da uno script è probabilmente correlato a unMENU.


1
bello, funziona alla grande (almeno dalla riga di comando, colpirà i sottomenu in seguito). Questo sembra aver lanciato parecchie persone ed è la prima volta che vedo una soluzione concreta. Vorrei solo avere abbastanza punti per votarti: D
richard plumb

Dannazione s ** t! Funziona anche se lo schermo è già collegato, senza ricollegarlo! Qual è un ottimo modo per inviare comandi ad app semplici da altre app nel sistema. Grazie! :)
Grzegorz Wierzowiecki,

Non ho mai avuto questo problema, probabilmente perché ho sempre pianificato di avere diverse finestre (denominate) nella mia sessione schermo e ho sempre scelto la finestra per nome.
Ekevoo,

Manuale, per riferimento: -X Invia il comando specificato a una sessione dello schermo in esecuzione. È possibile utilizzare l'opzione -S per specificare la sessione dello schermo se sono in esecuzione più sessioni dello schermo. È possibile utilizzare l'opzione -d o -r per indicare allo schermo di cercare solo le sessioni dello schermo collegate o staccate. Si noti che questo comando non funziona se la sessione è protetta da password.
KrisWebDev,

3
questo non funziona per me. Ho creato uno schermo con screen -d -m -S hie quindi eseguito screen -S hi -p 0 -X stuff "cd <some_directory>^M"e non ottengo nulla di conseguenza ... invia semplicemente "cd <directory_some> ^ M" come stringa e non interpreta "^ M" come tasto Invio ...
Tanner Strunk

23

Innanzitutto, una nota su come inserire facilmente le nuove righe:

Solo un avvertimento che il $()costrutto elimina le nuove righe dall'output del comando in modo che le righe di output possano essere utilizzate come argomenti per altri programmi. Ciò può causare comportamenti imprevisti. In questo caso suppongo che tu stia specificatamente cercando di inviare l'equivalente della Entersequenza di tasti. Mentre il ritorno a capo con il quale stai inviando \rnon verrà barrato, ci sono molti modi più semplici per inserire quel personaggio senza la necessità di un comando extra.

  1. È possibile inserire una nuova riga normale tra virgolette doppie

    screen -S minecraft -X stuff "stop
    "
    
  2. Oppure puoi inserire il carattere in una linea terminale usando la sequenza Ctrl+ v Enter. Sembrerà qualcosa di simile ^Mnel terminale, ma è un personaggio newline speciale.

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

In secondo luogo, una nota sul comportamento irregolare dello schermo. ( Spiegazione e soluzione di Gilles )

Lo schermo ha un problema con l'accettazione dell'input per una sessione dello schermo che non è mai stata allegata. Se lo esegui, non sarà riuscito:

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

Ma se esegui questo funzionerà:

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

Infine, potresti usare il comportamento molto migliore tmuxinvece di screen.

GNU-Screen è stato di fatto un multiplexer terminale di fatto per molti anni, ma ha smesso da tempo di essere sviluppato e bug e stranezze non vengono corretti. Tmux è in fase di sviluppo attivo, include molte funzionalità che lo schermo non può toccare e il suo comportamento è immediatamente più intuitivo. Inoltre, è meglio documentato. Ecco come convertire il codice:

# 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"

se passo manualmente usando lo schermo -r, posso vedere lo schermo e non viene inserito alcun testo. anche se il ritorno della carrozza non andava a buon fine, dovrei comunque digitare "stop". Ma niente
Richard Plumb,

se ho uno script con screen -r su una riga, e quindi screen -X roba "stop ^ M", allora ferma il server, ma si lamenta anche con 'errore unown opzione r'
richard plumb

Ho provato qui creando una sessione schermo, quindi usando il comando sopra e funziona perfettamente. Sei in grado di collegarti alla sessione dello schermo utilizzando screen -d -RR minecraft?
Caleb,

si, questo mi collega allo schermo. così lo schermo -r .. si blocca, se provo lo schermo -S minecraft -X roba "stop ^ M" quindi manualmente lo schermo -r, c'è il testo 'stop' sullo schermo.
Richard Plumb,

Per me va bene. Forse hai qualcosa .screenrcdi strano nella tua o hai un sacco di sessioni di schermo defunkt aperte con quel nome e quindi stai inviando dati a quello sbagliato? screen -list?
Caleb,

4

Mi scuso per aver scavato questo vecchio post, ma questo mi avrebbe aiutato nei miei sforzi se queste informazioni fossero state disponibili al momento in cui avevo un problema simile. Ci sono molte domande su come inviare i comandi dello schermo in uno script bash. Come per la pelle di gatto, questo può essere fatto, ma mi piace così. Con questo puoi inviare qualsiasi comando o dire qualsiasi cosa semplicemente chiamando la funzione 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"
...

Questo è con 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!"

Simpatico e conciso ... Benvenuto in U&L
eyoung100,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.