- Learn about Wiki
- Lectures
- Study
- Tips
쉘 명령을 실행하기 위해서는 다음과 같이 하면 된다.
(use '[clojure.java.shell :only [sh]]) >> nil (sh "ls" "-aul") >> {:exit 0, :out "total 64 drwxr-xr-x 11 zkim staff 374 Jul 5 13:21 . drwxr-xr-x 25 zkim staff 850 Jul 5 13:02 .. drwxr-xr-x 12 zkim staff 408 Jul 5 13:02 .git -rw-r--r-- 1 zkim staff 13 Jul 5 13:02 .gitignore -rw-r--r-- 1 zkim staff 12638 Jul 5 13:02 LICENSE.html -rw-r--r-- 1 zkim staff 4092 Jul 5 13:02 README.md drwxr-xr-x 2 zkim staff 68 Jul 5 13:15 classes drwxr-xr-x 5 zkim staff 170 Jul 5 13:15 lib -rw-r--r--@ 1 zkim staff 3396 Jul 5 13:03 pom.xml -rw-r--r--@ 1 zkim staff 367 Jul 5 13:15 project.clj drwxr-xr-x 4 zkim staff 136 Jul 5 13:15 src ", :err ""}
clojure.java.shell/sh의 소스코드 코드를 보면 실제로는java.lang.Runtime의 exec 메소드중 exec(String[] cmdarray, String[] envp, File dir) 를 사용하는데 다음과 같다.
(.exec (Runtime/getRuntime) ^"[Ljava.lang.String;" (into-array cmd) (as-env-strings (:env opts)) (as-file (:dir opts)))
Runtime.exec의 첫 인자는 (into-array cmd)의 결과로 스트링 배열이 된다. 그래서 위 코드에서 커맨드를 토큰별로 스트링으로 나열하여 sh 함수에 전달한 것이다. 하지만 이런 식으로 파이프를 사용할 수가 없다.
(sh "ls" "-l" "|" "wc" "-l") >>{:exit 2, :out "", :err "ls: |에 접근할 수 없습니다: 그런 파일이나 디렉터리가 없습니다\nls: wc에 접근할 수 없습니다: 그런 파일이나 디렉터리가 없습니다\n"}
파이프는 커맨드 쉘의 일부이기 때문이기 때문에 다음과 같이 해주어야 한다.
(sh "/bin/sh" "-c" "ls -l | wc -c") >> {:exit 0, :out "1227\n", :err ""}
다음과 같이 하면 출력문만 얻을 수 있다.
(print (:out (sh "/bin/sh" "-c" "ls -l | wc -c" :dir "/home/psk810/clojure/"))) => 1378 >> nil
다음과 같이 유틸리티 함수를 만들어 사용하면 편하다.
(defn mysh [& cmd] (:out (apply (partial clojure.java.shell/sh "/bin/sh" "-c") cmd))) >> #'user/mysh (def out (mysh "find -name \"*.clj\" | xargs wc -l" :dir "/home/psk810/clojure/nREPL")) >> #'user/s (print out) >> 215 ./clojure/tools/nrepl/middleware/session.clj 213 ./clojure/tools/nrepl/middleware/interruptible_eval.clj 90 ./clojure/tools/nrepl/middleware/load_file.clj 29 ./clojure/tools/nrepl/middleware/pr_values.clj 415 ./clojure/tools/nrepl/bencode.clj 233 ./clojure/tools/nrepl/t.clj 49 ./clojure/tools/nrepl/helpers.clj 163 ./clojure/tools/nrepl/middleware.clj 140 ./clojure/tools/nrepl/server.clj 88 ./clojure/tools/nrepl/cmdline.clj 168 ./clojure/tools/nrepl/transport.clj 54 ./clojure/tools/nrepl/misc.clj 52 ./clojure/tools/nrepl/ack.clj 246 ./clojure/tools/nrepl.clj 2155 합계 nil (def lines (clojure.string/split out #"\n")) (pprint lines) (def words (map #(re-seq #"\w+" %) lines)) (print words) (def numbers (map #(re-find #"\d+" %) lines)) (print numbers)