Подтвердить что ты не робот

Как работает "scala.sys.process" из Scala 2.9?

Я просто посмотрел на новые пакеты scala.sys и scala.sys.process, чтобы узнать, есть ли здесь что-то полезное. Однако я полностью потеряю.

Кто-нибудь получил пример о том, как начать процесс?

И, что наиболее интересно для меня: Можете ли вы отсоединить процессы?

Отключенный процесс будет продолжать работать, когда закончится родительский процесс и станет одним из слабых мест Ant.

UPDATE:

Кажется, есть какая-то путаница в том, что такое отряд. Приведите настоящий живой пример из моего текущего проекта. Однажды с z-Shell и один раз с помощью 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;

Take-Command:

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

В обоих случаях это огонь и забудьте, эмулятор запускается и будет продолжать работать даже после окончания script. Конечно, писать сценарии дважды - это отходы. Поэтому я рассматриваю Scala теперь для унифицированной обработки процессов без синтаксиса cygwin или xml.

4b9b3361

Ответ 1

Первый импорт:

import scala.sys.process.Process

затем создайте ProcessBuilder

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

Затем у вас есть два варианта:

  • запускать и блокировать до тех пор, пока процесс не завершится

    val exitCode = pb.!
    
  • запустите процесс в фоновом режиме (отсоединен) и получите экземпляр Process

    val p = pb.run
    

    Затем вы можете получить код выхода из процесса с помощью (если процесс все еще выполняется, он блокируется до тех пор, пока он не выйдет)

    val exitCode = p.exitValue
    

Если вы хотите обрабатывать ввод и вывод процесса, вы можете использовать ProcessIO:

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

Ответ 2

Я уверен, что отдельные процессы работают нормально, учитывая, что вы должны явно ждать его выхода, и вам нужно использовать потоки для babysit stdout и stderr. Это довольно просто, но это то, что я использовал:

/** Run a command, collecting the stdout, stderr and exit status */
def run(in: String): (List[String], List[String], Int) = {
  val qb = Process(in)
  var out = List[String]()
  var err = List[String]()

  val exit = qb ! ProcessLogger((s) => out ::= s, (s) => err ::= s)

  (out.reverse, err.reverse, exit)
}

Ответ 3

Процесс был импортирован из SBT. Вот подробное руководство по использованию библиотеки процессов, которое появляется в SBT.

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

Ответ 4

Кто-нибудь получил пример о том, как на самом деле начать процесс?

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

И, что наиболее интересно для меня: Можете ли вы отсоединить процессы?

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

Большая часть того, что вы сделаете, связана с sys.process.ProcessBuilder, признаком. Узнай это.

Есть неявки, которые делают использование менее подробным, и они доступны через объект пакета sys.process. Импортируйте его содержимое, как показано в примерах. Кроме того, взгляните на его скаладок.

Ответ 5

Следующая функция позволит легко использовать, если здесь документы:

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
}

К сожалению, я не смог (не успел) сделать операцию инфикса. Поэтому предлагаемое соглашение о вызове:

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

Это будет вызов, если кто-нибудь может дать мне подсказку о том, как сделать его более оболочкой, например:

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

Ответ 6

Процесс документирования немного лучше был вторым в моем списке, вероятно, через два месяца. Вы можете сделать мой список из того факта, что я так и не добрался до него. В отличие от большинства вещей, которые я не делаю, это то, что я сказал, что буду делать, поэтому я очень сожалею о том, что он остается недокументированным, как это было, когда оно прибыло. Меч, готов! Я падаю на тебя!

Ответ 7

Если я понимаю диалог до сих пор, один аспект исходного вопроса еще не ответил:

  • как "отсоединить" порожденный процесс, чтобы он продолжал работать независимо от родительского scala script

Основная трудность заключается в том, что все классы, участвующие в нерестах процесса, должны запускаться на JVM, и они неизбежно завершаются при выходе из JVM. Однако обходным путем является косвенное достижение цели, за счет использования оболочки для "отстранения" от вашего имени. Следующий scala script, который запускает редактор gvim, работает по желанию:

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

Предполагается, что scala находится в PATH, и он (неизбежно) оставляет родительский процесс JVM также.