Scala 2.9의 "scala.sys.process"는 어떻게 작동합니까?
여기에 도움이되는 것이 있는지 확인하기 위해 새 패키지 scala.sys
와 scala.sys.process
패키지를 방금 살펴 보았습니다 . 그러나 나는 완전한 손실에 처해 있습니다.
실제로 프로세스를 시작하는 방법에 대한 예제가있는 사람이 있습니까?
그리고 저에게 가장 흥미로운 것은 무엇입니까? 프로세스를 분리 할 수 있습니까?
분리 된 프로세스는 상위 프로세스가 종료 될 때 계속 실행되며 Ant의 약점 중 하나입니다.
최신 정보:
분리가 무엇인지 약간의 혼란이있는 것 같습니다. 내 현재 프로젝트의 실제 사례가 있습니다. z-Shell에서 한 번, TakeCommand에서 한 번 :
Z- 쉘 :
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;
테이크 커맨드 :
IFF %@Connect[localhost 5554] lt 0 THEN
ECHO [TCC] Start emulator
DETACH emulator -avd Nexus-One -no-boot-anim
ENDIFF
두 경우 모두 실행되고 잊어 버리고 에뮬레이터가 시작되고 스크립트가 종료 된 후에도 계속 실행됩니다. 물론 대본을 두 번 작성하는 것은 낭비입니다. 그래서 지금은 cygwin 또는 xml 구문없이 통합 된 프로세스 처리를 위해 Scala를 살펴 봅니다.
첫 번째 가져 오기 :
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)
I'm pretty sure detached processes work just fine, considering that you have to explicitly wait for it to exit, and you need to use threads to babysit the stdout and stderr. This is pretty basic, but it's what I've been using:
/** 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)
}
Process was imported from SBT. Here's a thorough guide on how to use the process library as it appears in SBT.
https://github.com/harrah/xsbt/wiki/Process
Has anybody got an example on how to actually start a process?
import sys.process._ // Package object with implicits!
"ls"!
And, which is most interesting for me: Can you detach processes?
"/path/to/script.sh".run()
Most of what you'll do is related to sys.process.ProcessBuilder
, the trait. Get to know that.
There are implicits that make usage less verbose, and they are available through the package object sys.process
. Import its contents, like shown in the examples. Also, take a look at its scaladoc as well.
The following function will allow easy use if here 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
}
Sadly I was not able to (did not have the time to) to make it an infix operation. Suggested calling convention is therefore:
#<<< ("command") {"""
Here Document data
"""}
It would be call if anybody could give me a hint on how to make it a more shell like call:
"command" #<<< """
Here Document data
""" !
Documenting process a little better was second on my list for probably two months. You can infer my list from the fact that I never got to it. Unlike most things I don't do, this is something I said I'd do, so I greatly regret that it remains as undocumented as it was when it arrived. Sword, ready yourself! I fall upon thee!
If I understand the dialog so far, one aspect of the original question is not yet answered:
- how to "detach" a spawned process so it continues to run independently of the parent scala script
The primary difficulty is that all of the classes involved in spawning a process must run on the JVM, and they are unavoidably terminated when the JVM exits. However, a workaround is to indirectly achieve the goal by leveraging the shell to do the "detach" on your behalf. The following scala script, which launches the gvim editor, appears to work as desired:
val cmd = List( "scala", "-e", """import scala.sys.process._ ; "gvim".run ; System.exit(0);""" ) val proc = cmd.run
It assumes that scala is in the PATH, and it does (unavoidably) leave a JVM parent process running as well.
참고URL : https://stackoverflow.com/questions/6013415/how-does-the-scala-sys-process-from-scala-2-9-work
'Development Tip' 카테고리의 다른 글
부울 값 전환 / 반전 (0) | 2020.12.07 |
---|---|
흥미로운 '정확히 1 개의 인수 (2 개 제공)를 취함'Python 오류 (0) | 2020.12.07 |
MPI : 차단 vs 비 차단 (0) | 2020.12.07 |
MongoDB : 배열 내의 인덱스가 참조하는 배열의 단일 하위 요소를 어떻게 업데이트합니까? (0) | 2020.12.07 |
스토리 보드 UIViewcontroller, '사용자 정의 클래스'가 드롭 다운에 표시되지 않음 (0) | 2020.12.07 |