2010-01-01 7 views
2

Est-il possible d'effectuer une opération d'E/S en cours? J'ai plusieurs serveurs de jeu en cours d'exécution comme ceci:Linux i/o pour exécuter le démon/processus

cd /path/to/game/server/binary 
./binary arg1 arg2 ... argn & 

Est-il possible d'écrire un message à un serveur si je sais que l'ID de processus?

Quelque chose comme ça serait pratique:

echo "quit" > process1234 

Où process1234 est le processus (avec sid 1234).

Le serveur de jeu n'est pas un binaire écrit par moi, mais un binaire Call of Duty. Donc je ne peux rien changer au code.

+0

Edité ma réponse avec une suggestion plus générale. – Omnifarious

Répondre

1

Oui, vous pouvez démarrer le processus avec un tube en tant que stdin, puis écrire dans le tube. Vous pouvez utiliser un tuyau nommé ou anonyme.

Normalement, un processus parent serait nécessaire pour cela, ce qui créerait un tube anormal et fournirait cela au processus fils comme le fait stdin-popen(), de nombreuses bibliothèques l'implémentent également (voir IPC :: Open2 de Perl par exemple)

Une autre façon serait de l'exécuter sous un pseudo tty, ce que fait "screen". L'écran lui-même peut également avoir un mécanisme pour le faire.

+0

Je pense que je vais utiliser l'écran. D'abord je dois apprendre à utiliser ceci: P – VDVLeon

+1

Il existe des alternatives à l'écran GNU, par exemple http://www.cliki.net/detachtty et http://caca.zoy.org/wiki/neercs - en fait, le premier peut être plus simple d'interagir avec, par programme. – ephemient

1

Seulement si le processus écoute un message quelque part. Par exemple, votre serveur de jeu peut attendre une entrée sur un fichier, sur une connexion réseau ou à partir d'une entrée standard.

Si votre processus n'écoute pas activement quelque chose, les seules choses que vous pouvez vraiment faire est de l'arrêter ou de le tuer.

Maintenant, si votre processus est en attente sur l'entrée standard, et vous l'avez exécuté comme ceci:

$ myprocess & 

Ensuite (sous Linux), vous devriez être en mesure d'essayer ce qui suit:

$ jobs 
[1]+ Running     myprocess & 
$ fg 1 

Et À ce stade, vous tapez une entrée standard dans votre processus.

+0

Le serveur dispose d'une console d'entrée pour les commandes. La commande quitter quitte le serveur. Je peux tuer mais ensuite je me suis trompé de fichiers journaux. Je veux donc quitter le serveur comme il se doit. Donc, le serveur écoute stdin. – VDVLeon

+0

le travail n'existe plus (plus). Peut-être parce que le serveur est démarré par un script cronjob et qu'aucun travail n'est stocké? – VDVLeon

1

Vous ne pouvez le faire que si le processus est explicitement conçu pour cela.

Mais puisque votre exemple demande le processus de quitter, je vous recommande d'essayer des signaux. Tout d'abord essayer d'envoyer le signal de TERM (c.-à-fin) qui est la valeur par défaut:

kill _pid_ 

Si cela ne fonctionne pas, vous pouvez essayer d'autres signaux tels que QUIT:

kill -QUIT _pid_ 

Si tout le reste échoue , vous pouvez utiliser le signal KILL. Ceci est garanti (*) pour arrêter le processus, mais le processus aura aucun changement pour nettoyer:

kill -KILL _pid_ 

* - dans le passé, kill -KILL ne fonctionnerait pas si le processus a été pendu lors d'un serveur de fichiers réseau squameuse . Je ne sais pas s'ils ont déjà réglé ça.

+0

L'état "D" (http://en.wikipedia.org/wiki/Uninterruptible_sleep) a plusieurs causes, l'attente de l'E/S NFS étant l'un des cas les plus fréquents. Linux a progressé vers l'élimination de certains d'entre eux en faveur des interruptions interruptibles, mais de nombreux appels système sont impossibles à redémarrer s'ils sont interrompus. – ephemient

1

Je suis assez sûr que cela fonctionnerait, car le serveur dispose d'une console sur stdin:

echo "quit" > /proc/<server pid>/fd/0 

Vous mentionnez dans un commentaire ci-dessous que votre processus ne semble pas lire à partir de la console sur fd 0. Mais il doit sur certains fd. ls -l /proc/<server pid/>/fd/ et recherchez-en un pointant vers/dev/pts/si le processus s'exécute dans un gnome-terminal ou xterm ou un autre.

+0

si je cours: ln -al/proc//fd/0 je reçois: lr-x ------ 1 root root 64 jan 1 23:00 0 ->/dev/null Donc il n'y a pas flux d'entrée. Je me suis souvenu de quelque chose. Le serveur a une ligne d'entrée de console, toujours au bas de votre console Linux. Alors peut-être qu'il a utilisé ncurses (ou quelque chose) pour lire l'entrée. Peut-être alors il y a un autre fd pour cette ligne d'entrée de la console? – VDVLeon

0

Si vous souhaitez effectuer quelques opérations simples sur votre serveur, utilisez les signaux mentionnés ailleurs. Configurez les gestionnaires de signaux dans le serveur et demandez à chaque signal d'effectuer une action différente, par ex.:

  • SIGINT: fichier de configuration Relire
  • SIGHUP: quitter

...

0

Très hackish, ne le faites pas si vous avez une alternative plus saine, mais vous pouvez rediriger Les descripteurs de fichiers d'un processus à la volée si vous avez des permissions ptrace.

 
$ echo quit > /tmp/quitfile 
$ gdb binary 1234 
(gdb) call dup2(open("/tmp/quitfile", 0), 0) 
(gdb) continue 

open("/tmp/quitfile", O_RDONLY) renvoie un descripteur de fichier à /tmp/quitfile. dup2(..., STDIN_FILENO) remplace l'entrée standard existante par le nouveau descripteur de fichier.

Nous injectons ce code dans l'application en utilisant gdb (mais avec des constantes numériques, car les constantes #define peuvent ne pas être disponibles), et taadaah.

0

Il suffit de l'exécuter sous l'écran et de ne pas l'arrière-plan. Ensuite, vous pouvez soit vous connecter à l'écran avec interactivité et lui dire de quitter, ou (avec un peu de s'attendre à un piratage) écrire un script qui se connectera à l'écran, envoyer le message de quitter, et se déconnecter.

Questions connexes