2010-11-02 4 views
1

J'ai un petit script qui se lance et, toutes les demi-heures, envoie une commande à un programme Java (gestionnaire de serveur de jeu) comme si l'utilisateur le tapait. Cependant, après avoir lu la documentation et expérimenté, je ne peux pas comprendre comment je peux obtenir deux choses:Tuyauterie d'entrée Python et sous-processus

1) Une version qui permet à l'utilisateur de taper des commandes dans le terminal windoe et ils seront envoyés à l'entrée du gestionnaire de serveur tout comme la commande "save-all".

2) Une version qui reste en cours d'exécution, mais envoie une nouvelle entrée au système lui-même, supprimant le besoin d'une seconde fenêtre de terminal. Celui-ci est en train de se produire en ce moment même quand quelque chose est tapé, il n'y a pas de retour visuel, mais une fois le programme terminé, il est clair que le terminal a reçu l'entrée. Par exemple, une liste du contenu du répertoire sera là si "dir" a été tapé pendant l'exécution du programme. Celui-ci est plus pour la compréhension que la commodité.

Merci pour l'aide. Voici le script:

from time import sleep 
import sys,os 
import subprocess 


# Launches the server with specified parameters, waits however 
# long is specified in saveInterval, then saves the map. 


# Edit the value after "saveInterval =" to desired number of minutes. 
# Default is 30 

saveInterval = 30 

# Start the server. Substitute the launch command with whatever you please. 
p = subprocess.Popen('java -Xmx1024M -Xms1024M -jar minecraft_server.jar', 
        shell=False, 
        stdin=subprocess.PIPE); 

while(True): 

    sleep(saveInterval*60) 

    # Comment out these two lines if you want the save to happen silently. 
    p.stdin.write("say Backing up map...\n") 
    p.stdin.flush() 

    # Stop all other saves to prevent corruption. 
    p.stdin.write("save-off\n") 
    p.stdin.flush() 
    sleep(1) 

    # Perform save 
    p.stdin.write("save-all\n") 
    p.stdin.flush() 
    sleep(10) 

    # Allow other saves again. 
    p.stdin.write("save-on\n") 
    p.stdin.flush() 

Répondre

2

Remplacez votre sleep() par un appel à select((sys.stdin,),(),(), saveInterval*60) - qui aura le même délai d'attente, mais écoute sur stdin pour les commandes utilisateur. Lorsque select indique que vous avez entré, lisez une ligne de sys.stdin et l'alimentez à votre processus. Lorsque select indique un délai d'expiration, exécutez la commande "save" que vous êtes en train de faire.

+0

Génial, je n'avais pas entendu parler de ça. Merci. – Sean

+0

À titre d'avertissement - vous ne mentionnez pas sur quelle plate-forme vous êtes - 'select' peut ne pas fonctionner correctement sur win32. Je ne connais que * nix. – bstpierre

1

Il ne résoudra pas complètement votre problème, mais vous trouverez peut-être modules Python cmd utile. C'est un moyen d'implémenter facilement une boucle de ligne de commande extensible (souvent appelée REPL).

+0

Je peux essayer de restructurer un peu, dans ce cas, cmd pourrait être très utile. Merci pour la suggestion. – Sean

1

Vous pouvez exécuter le programme à l'aide de l'écran, puis vous pouvez envoyer l'entrée à la session d'écran spécifique au lieu du programme directement (si vous êtes dans Windows installez simplement cygwin).