Je souhaite exécuter un serveur de jeu dans ma machine Ubuntu. Je veux l'exécuter en arrière-plan et écrire la sortie en direct de ce processus dans un fichier journal. J'ai essayé d'utiliser nohup et d'exécuter le serveur de jeu en utilisant "&" à la fin, mais je n'ai pas pu le faire fonctionner comme je le souhaitais.
Ensuite, j'ai commencé à lire sur les tubes nommés et j'ai essayé. J'ai fait un script simple qui en théorie devrait fonctionner. Mais, bien sûr, il me manque quelque chose.
D'abord, j'ai créé un tube en utilisant la commande mkfifo.
#!/bin/bash newport=$(shuf -i 22003-22900 -n 1) newip=$(shuf -i 22003-22900 -n 1) rm -rf ~/server/* cp -r /home/user*/ftp/server/mtaserver/serverfiles/* ~/server sed -i "s/<httpport>[0-9][0-9][0-9][0-9][0-9]<\/httpport>/<httpport>$newport<\/httpport>/g" ~/server/mods/deathmatch/mtaserver.conf sed -i "s/<serverport>[0-9][0-9][0-9][0-9][0-9]<\/serverport>/<serverport>$newip<\/serverport>/g" ~/server/mods/deathmatch/mtaserver.conf ~/server/mta-server64 2>&1 | tee -a outfile & mta_pid=$! echo $mta_pid sleep 6 pkill $mta_pid
Ensuite, j'ai créé un petit script:
[|] MTA: San Andreas :: 0/32 players :: 196 resources :: 125 fps (25) MTA:BLUE Server for MTA:SA ================================================================== = Multi Theft Auto: San Andreas v1.5.6 [64 bit] ================================================================== = Server name : Default MTA Server = Server IP address: auto = Server port : 22884 = = Log file : /root/mta/mods/deathmatch/logs/server.log = Maximum players : 32 = HTTP port : 22564 = Voice Chat : Disabled = Bandwidth saving : Medium ================================================================== [09:49:07] Resource 'mapmanager' requests some acl rights. Use the command 'aclrequest list mapmanager' [09:49:07] Resources: 196 loaded, 0 failed [09:49:07] Starting resources... [09:49:07] Server minclientversion is now 1.5.6-9.16588.0 [09:49:07] INFO: MAPMANAGER: Some important ACL permissions are missing. To ensure the correct functioning of Mapmanager, please write: aclrequest allow mapmanager all [09:49:07] Gamemode 'play' started. [09:49:07] Authorized serial account protection is enabled for the ACL group(s): `Admin` See http://mtasa.com/authserial [09:49:07] WARNING: <owner_email_address> not set [09:49:07] Server started and is ready to accept connections! [09:49:07] To stop the server, type 'shutdown' or press Ctrl-C [09:49:07] Type 'help' for a list of commands. [09:49:07] Querying MTA master server... success! (Auto detected IP:xxx.xxx.xxx.xxx)
(Note: j'ai écrit ce code de mémoire.)
Le code ne fonctionne que lorsqu'il y a une erreur et que le processus s'arrête. Il enregistre en fait l'erreur de la console de jeu. Mais lorsque le serveur de jeu est en cours d'exécution, je n'obtiens aucune sortie dans le fichier journal.
Je veux lire la sortie (stdout et stderr si je ne me trompe pas) d'un processus s'exécutant en arrière-plan et les enregistrer à l'intérieur un fichier journal.
J'ai aussi pensé à utiliser screen car il enregistre tout dans un fichier mais je préférerais ne pas l'utiliser s'il y a une meilleure solution.
EDIT:
Tout d'abord: merci de l'intérêt que vous portez à m'aider. De la même manière, je dois m'excuser de ne donner que de rares détails sur ce que j'ai l'intention de faire avec ce petit projet et pour ma compréhension limitée de stdout et stderr.
Passons à la première base. p>
Je souhaite exécuter un serveur de jeu nommé Multi Theft Auto ( https://multitheftauto.com/ ). C'est GTA San Andreas mais multijoueur.
Je peux facilement exécuter ce serveur de jeu dans mon serveur Ubuntu en appelant l'exécutable ./mta-server-64
. Après l'avoir appelé, la console du serveur de jeu apparaît:
#!/bin/bash ./mta-server64 > pipe & pid=$! echo $pid // so I know the pid of the process cat < pipe > log.txt &
J'utilise le script suivant pour exécuter le processus en arrière-plan et (j'essaie) d'obtenir la sortie en direct de: p>
mkfifo testpipe
(Note: En raison de problèmes techniques, j'ai dû ajouter les premières lignes de script qui remplacent automatiquement les fichiers du jeu par de nouveaux et remplacent également les ports existants par des ports aléatoires. )
Ce script démarre le serveur et essaie de consigner la sortie du processus. Le processus est automatiquement tué après quelques secondes, il n'y a donc qu'une seule instance du serveur de jeu à un moment donné.
LE PROBLÈME:
Ce script uniquement enregistre la sortie s'il y a une erreur. Je ne parviens toujours pas à obtenir la sortie en direct du processus lorsqu'il est toujours en cours d'exécution. C'est peut-être un problème avec le serveur de jeu, mais je crois vraiment qu'il devrait y avoir un moyen de le faire fonctionner comme je l'entends.
3 Réponses :
Je pense que vous souhaitez utiliser la commande tee
pour diviser la sortie du tube en fichier journal.
J'ai examiné ces liens. J'ai essayé la méthode du tee mais le résultat est le même. Aucune journalisation de sortie n'est effectuée pendant que le processus s'exécute avec succès.
le tee
capture stdout
et / ou stderr
assurez-vous que l'application génère le journal requis dans stdout
. Assurez-vous de comprendre comment le journal est généré et quand il est prêt pour la lecture.
J'ai une compréhension limitée de la façon dont le serveur de jeu génère le stdout et le stdout en général. J'ai essayé de suivre des tutoriels dans l'espoir de le comprendre tout en les travaillant.
Habituellement, cela suffit nohup somecommand> somecommand.log 2> & 1 &
puis, tail -F somecommand.log
pour suivre les journaux.
J'ai essayé cette méthode mais le résultat est le même: pendant que le processus est en cours d'exécution, la sortie ne sera pas enregistrée dans le fichier. Il n'enregistre que lorsqu'il y a une erreur.
stdout est tamponné en ligne, tandis que stderr est sans tampon, votre commande affiche-t-elle des éléments dans stdout sous forme de lignes?
Si vous exécutez le serveur sans rien d'autre, imprime-t-il quelque chose sur la sortie standard?
Si je lance l'exécutable, il affiche la console de jeu où je peux écrire des commandes directement sur le serveur de jeu.
Au bout de 2 jours, j'ai finalement trouvé un moyen de le faire fonctionner (comme je prévoyais de travailler, sans prendre en compte les risques majeurs de sécurité / performance).
La lecture des commentaires m'a fait réaliser que j'attaquais le mauvais point. La sortie standard du serveur de jeu est mise en mémoire tampon, ce qui rend impossible sa connexion dans un fichier journal en utilisant les méthodes que j'ai essayées lorsque j'ai posté ma question Au moins c'est ce que j'ai compris).
J'ai fait quelques recherches sur la façon d'exécuter l'application sans avoir le stdout mis en mémoire tampon: https://serverfault.com/questions/294218/is-there-a-way-to-redirect-output-to-a-file-without-buffering-on- unix-linux
Mon code maintenant:
stdbuf -o0 ~/server/mta-server64 >> pipe & cat < pipe | tee -a outfile &
Après avoir créé le tube nommé, il exécute le serveur de jeu à l'intérieur de ce tube et ajoute le stdout dans le fichier journal.
La commande stdbug -o0
désactive la mise en mémoire tampon stdout (comme indiqué dans le lien ci-dessus).
Cela fonctionne pour moi et Je ne peux garantir que cela fonctionnera pour quiconque. Je ne sais toujours pas si la désactivation de la mise en mémoire tampon est une approche sûre à mon problème, mais pour l'instant c'est ce dont j'ai besoin.