[scala] 쉘 실행하기

scala 2016. 12. 13. 20:24



 scala에서 프로세스를 실행하려면 scala.sys.process._을 import하고, 문자열에 .! (또는 !)을 실행한다. (마치 regular expression처럼..) 


import scala.sys.process._
val result = "ls -al /Users/samuel.kim/dev".!
println(result)

결과는 다음과 같다. 


total 48

drwxr-xr-x   8 samuel.kim  staff   272 12 11 01:02 .

drwxr-xr-x+ 64 samuel.kim  staff  2176 12 12 18:20 ..

-rw-r--r--   1 samuel.kim  staff     8 12 12 21:48 a

-rw-r--r--   1 samuel.kim  staff     8 12 11 01:02 b

..

0


주의할 점은 !는 ProcessBuilder 클래스의 메소드로서 리턴 값은 Int이다. 즉, 결과를 출력하고 리턴 값으로 0만 받는 형태이다. 


def ! : Int


전체 결과를 String으로 얻으려면, !!을 사용한다. 


import scala.sys.process._
val result = "ls -al /Users/samuel.kim/dev".!!
println(result)


결과는 다음과 같다.


total 48

drwxr-xr-x   8 samuel.kim  staff   272 12 11 01:02 .

drwxr-xr-x+ 64 samuel.kim  staff  2176 12 12 18:20 ..

-rw-r--r--   1 samuel.kim  staff     8 12 12 21:48 a

-rw-r--r--   1 samuel.kim  staff     8 12 11 01:02 b

..



!!의 리턴 값은 String이다. 

def !! : String





그리고, List로 저장할 수 있다. 

import scala.sys.process._
val result = List("ls -al /Users/samuel.kim/dev".!!)
result.foreach(println)
println(result.size)

결과는 다음과 같다. 


total 48

drwxr-xr-x   8 samuel.kim  staff   272 12 11 01:02 .

drwxr-xr-x+ 64 samuel.kim  staff  2176 12 12 18:20 ..

-rw-r--r--   1 samuel.kim  staff     8 12 12 21:48 a

-rw-r--r--   1 samuel.kim  staff     8 12 11 01:02 b

..

1






파이프라인을 사용하면, 에러가 발생한다.

import scala.sys.process._
val result = List("ls -al /Users/samuel.kim/dev | wc -l".!!)
result.foreach(println)


ls: a: No such file or directory

ls: grep: No such file or directory

ls: |: No such file or directory




다음처럼 커맨드 단위로 잘개 쪼개고 #을 파이프에 붙여야 한다. 


import scala.sys.process._
val result = List(("ls -al /Users/samuel.kim/dev" #| "wc -l ").!!)
result.foreach(println)

결과는 다음과 같다. 





이번에는 >>이라는 표준 출력(stdout) append를 사용한다. #|처럼 #>>을 사용하며, #>> 다음에는 new File()을 생성한다. 


import java.io.File
import scala.sys.process._
val result = ("ls -al /Users/samuel.kim/dev" #| "wc -l " #>> new File(s"/Users/samuel.kim/dev/a.txt")).!
println(result)
val result2 = ("cat /Users/samuel.kim/dev/a.txt".!!)
println(result2)


결과는 다음과 같다.


0

       8



스칼라에서는 표준 입력/출력을 처리할 수 있다.


#<   Redirect STDIN


#>   Redirect STDOUT

#>>  Append to STDOUT


#&&  Create an AND list

#!!  Create an OR list



자세한 내용은 scala.sys.process.ProcessBuilder api를 참조한다.





이를 바탕으로 함수를 만들 수 있다. 


def get(filter: String) = {
val command = s"ls -al /Users/samuel.kim/dev" #| s"grep $filter "
println(command)
command
}

val result = get("xx").!!
println(result)

결과는 다음과 같다.


 ( [ls, -al, /Users/samuel.kim/dev] #| [grep, xx] ) 

drwxr-xr-x   9 samuel.kim  staff   306 Dec  5 21:16 xx





scala는 쉘의 리턴값이 정상이 아니면 Exception이 발생한다. Try를 써주면 Exception 대신 Failure로 처리해 준다.


def get(filter: String) = {
val command = s"ls -al /Users/samuel.kim/dev" #| s"grep $filter "
println(command)
command
}

val result = Try(get("bbb").!!)
println(result)

결과는 다음과 같다.


 ( [ls, -al, /Users/samuel.kim/dev] #| [grep, bbb] ) 

Failure(java.lang.RuntimeException: Nonzero exit value: 1)

Posted by '김용환'
,