Comment fonctionne le «scala.sys.process» de Scala 2.9?

J’ai juste jeté un coup d’oeil aux nouveaux scala.sys et scala.sys.process pour voir s’il y a quelque chose d’utile ici. Cependant, je suis complètement perdu.

Quelqu’un at-il un exemple sur la façon de démarrer un processus?

Et, ce qui est le plus intéressant pour moi: pouvez-vous détacher des processus?

Un processus détaché continuera à fonctionner lorsque le processus parent se terminera et sera l’un des points faibles de Ant.

METTRE À JOUR:

Il semble y avoir une certaine confusion dans ce que détachement est. Ayez un véritable exemple concret de mon projet actuel. Une fois avec z-Shell et une fois avec TakeCommand:

Z-Shell:

 if ! ztcp localhost 5554; then echo "[ZSH] Start emulator" emulator \ -avd Nexus-One \ -no-boot-anim \ 1>~/Library/Logs/${PROJECT_NAME}-${0:t:r}.out \ 2>~/Library/Logs/${PROJECT_NAME}-${0:t:r}.err & disown else ztcp -c "${REPLY}" fi; 

Prendre commande:

 IFF %@Connect[localhost 5554] lt 0 THEN ECHO [TCC] Start emulator DETACH emulator -avd Nexus-One -no-boot-anim ENDIFF 

Dans les deux cas, il est déclenché et oublié, l’émulateur est démarré et continuera à s’exécuter même après la fin du script. Bien sûr, écrire deux fois les scripts est un gaspillage. Je me penche donc maintenant sur Scala pour la gestion unifiée des processus sans la syntaxe cygwin ou xml.

Première importation:

 import scala.sys.process.Process 

puis créez un ProcessBuilder

 val pb = Process("""ipconfig.exe""") 

Ensuite, vous avez deux options:

  1. exécuter et bloquer jusqu’à ce que le processus se termine

     val exitCode = pb.! 
  2. exécuter le processus en arrière-plan (détaché) et obtenir une instance de Process

     val p = pb.run 

    Ensuite, vous pouvez obtenir le code de sortie du processus avec (si le processus est toujours en cours d’exécution, il bloque jusqu’à ce qu’il se ferme)

     val exitCode = p.exitValue 

Si vous voulez gérer l’entrée et la sortie du processus, vous pouvez utiliser ProcessIO :

 import scala.sys.process.ProcessIO val pio = new ProcessIO(_ => (), stdout => scala.io.Source.fromInputStream(stdout) .getLines.foreach(println), _ => ()) pb.run(pio) 

Je suis presque sûr que les processus détachés fonctionnent correctement, étant donné que vous devez explicitement attendre sa sortie, et que vous devez utiliser des threads pour garder le stdout et le stderr. C’est assez basique, mais c’est ce que j’utilise:

 /** Run a command, collecting the stdout, stderr and exit status */ def run(in: Ssortingng): (List[Ssortingng], List[Ssortingng], Int) = { val qb = Process(in) var out = List[Ssortingng]() var err = List[Ssortingng]() val exit = qb ! ProcessLogger((s) => out ::= s, (s) => err ::= s) (out.reverse, err.reverse, exit) } 

Le processus a été importé de SBT. Voici un guide détaillé sur l’utilisation de la bibliothèque de processus telle qu’elle apparaît dans SBT .

https://github.com/harrah/xsbt/wiki/Process

Quelqu’un at-il un exemple sur la façon de démarrer un processus?

 import sys.process._ // Package object with implicits! "ls"! 

Et, ce qui est le plus intéressant pour moi: pouvez-vous détacher des processus?

 "/path/to/script.sh".run() 

La plupart de ce que vous allez faire est lié à sys.process.ProcessBuilder , le trait. Apprenez à le savoir

Il existe des implicits qui rendent l’utilisation moins détaillée, et ils sont disponibles via l’object sys.process du package. Importez son contenu, comme indiqué dans les exemples. Jetez également un coup d’œil à son scaladoc.

La fonction suivante permettra une utilisation facile si ici des documents:

 def #<<< (command: String) (hereDoc: String) = { val process = Process (command) val io = new ProcessIO ( in => {in.write (hereDoc getBytes "UTF-8"); in.close}, out => {scala.io.Source.fromInputStream(out).getLines.foreach(println)}, err => {scala.io.Source.fromInputStream(err).getLines.foreach(println)}) process run io } 

Malheureusement, je n’ai pas été capable (de ne pas avoir le temps de le faire) d’en faire une opération infixe. La convention d’appel suggérée est donc:

 #<<< ("command") {""" Here Document data """} 

Ce serait un appel si quelqu'un pouvait me donner un indice sur la façon de faire un appel plus shell:

 "command" #<<< """ Here Document data """ ! 

Le processus de documentation un peu mieux était probablement le deuxième sur ma liste depuis probablement deux mois. Vous pouvez déduire ma liste du fait que je ne l’ai jamais eu. Contrairement à la plupart des choses que je ne fais pas, c’est quelque chose que j’ai dit que je ferais, alors je regrette énormément que cela ne soit pas aussi documenté qu’au moment de son arrivée. Épée, préparez-vous! Je tombe sur toi!

Si j’ai bien compris la boîte de dialog, un aspect de la question initiale n’a pas encore reçu de réponse:

  1. comment “détacher” un processus généré pour qu’il continue à fonctionner indépendamment du script scala parent

La principale difficulté réside dans le fait que toutes les classes impliquées dans la création d’un processus doivent s’exécuter sur la machine virtuelle Java et qu’elles sont inévitablement terminées à la fermeture de la machine virtuelle Java. Cependant, une solution de contournement consiste à atteindre indirectement l’objective en exploitant le shell pour effectuer le “détachement” en votre nom. Le script scala suivant, qui lance l’éditeur gvim, semble fonctionner comme souhaité:

 val cmd = Liste (
    "scala",
    "-e",
    "" "import scala.sys.process._;" gvim ".run; System.exit (0);" ""
 )
 val proc = cmd.run

Cela suppose que scala est dans le PATH et laisse (inévitablement) un processus parent JVM en cours d’exécution.