当前位置:K88软件开发文章中心编程语言非主流编程语言Julia → 文章内容

Julia 运行外部程序

减小字体 增大字体 作者:佚名  来源:网上搜集  发布时间:2019-1-15 16:28:26

由 陈 创建, 最后一次修改 2016-08-12 运行外部程序Julia 使用倒引号 ` 来运行外部程序: julia> `echo hello` `echo hello`它有以下几个特性:倒引号并不直接运行程序,它构造一个 Cmd 对象来表示这个命令。可以用这个对象,通过管道将命令连接起来,运行,并进行读写命令运行时,除非指明, Julia 并不捕获输出。它调用 libc 的 system ,命令的输出默认指向 stdout 。命令运行不需要 shell 。 Julia 直接解析命令语法,对变量内插,像 shell 一样分隔单词,它遵循 shell 引用语法。命令调用 fork 和 exec 函数,作为 julia 的直接子进程。下面是运行外部程序的例子: julia> run(`echo hello`) hellohello 是 echo 命令的输出,它被送到标准输出。 run 方法本身返回 nothing 。如果外部命令没有正确运行,将抛出 ErrorException 异常。使用 readall 读取命令的输出: julia> a=readall(`echo hello`) "hello\n" julia> (chomp(a)) == "hello" true更普遍的,你可以使用 open 从一个外部命令读取或者写到一个外部命令。例如: julia> open(`less`, "w", STDOUT) do io for i = 1:1000 println(io, i) end end内插将文件名赋给变量 file ,将其作为命令的参数。像在字符串文本中一样使用 $ 做内插(详见 :ref:man-strings ): julia> file = "/etc/passwd" "/etc/passwd" julia> `sort $file` `sort /etc/passwd`如果文件名有特殊字符,比如 /Volumes/External HD/data.csv ,会如下显示: julia> file = "/Volumes/External HD/data.csv" "/Volumes/External HD/data.csv" julia> `sort $file` `sort '/Volumes/External HD/data.csv'`文件名被单引号引起来了。Julia 知道 file 会被当做一个单变量进行内插,它自动把内容引了起来。事实上,这也不准确: file 的值并不会被 shell 解释,所以不需要真正的引起来;此处把它引起来,只是为了给用户显示。下例也可以正常运行: julia> path = "/Volumes/External HD" "/Volumes/External HD" julia> name = "data" "data" julia> ext = "csv" "csv" julia> `sort $path/$name.$ext` `sort '/Volumes/External HD/data.csv'`如果要内插多个单词,应使用数组(或其它可迭代容器): julia> files = ["/etc/passwd","/Volumes/External HD/data.csv"] 2-element ASCIIString Array: "/etc/passwd" "/Volumes/External HD/data.csv" julia> `grep foo $files` `grep foo /etc/passwd '/Volumes/External HD/data.csv'`如果数组内插为 shell 单词的一部分,Julia 会模仿 shell 的 {a,b,c} 参数生成的行为: julia> names = ["foo","bar","baz"] 3-element ASCIIString Array: "foo" "bar" "baz" julia> `grep xylophone $names.txt` `grep xylophone foo.txt bar.txt baz.txt`如果将多个数组内插进同一个单词,Julia 会模仿 shell 的笛卡尔乘积生成的行为: julia> names = ["foo","bar","baz"] 3-element ASCIIString Array: "foo" "bar" "baz" julia> exts = ["aux","log"] 2-element ASCIIString Array: "aux" "log" julia> `rm -f $names.$exts` `rm -f foo.aux foo.log bar.aux bar.log baz.aux baz.log`不构造临时数组对象,直接内插文本化数组: julia> `rm -rf $["foo","bar","baz","qux"].$["aux","log","pdf"]` `rm -rf foo.aux foo.log foo.pdf bar.aux bar.log bar.pdf baz.aux baz.log baz.pdf qux.aux qux.log qux.pdf`引用命令复杂时,有时需要使用引号。来看一个 perl 的命令: sh$ perl -le '$|=1; for (0..3) { print }' 0 1 2 3再看个使用双引号的命令: sh$ first="A" sh$ second="B" sh$ perl -le '$|=1; print for @ARGV' "1: $first" "2: $second" 1: A 2: B一般来说,Julia 的倒引号语法支持将 shell 命令原封不动的复制粘贴进来,且转义、引用、内插等行为可以原封不动地正常工作。唯一的区别是,内插被集成进了 Julia 中: julia> `perl -le '$|=1; for (0..3) { print }'` `perl -le '$|=1; for (0..3) { print }'` julia> run(ans) 0 1 2 3 julia> first = "A"; second = "B"; julia> `perl -le 'print for @ARGV' "1: $first" "2: $second"` `perl -le 'print for @ARGV' '1: A' '2: B'` julia> run(ans) 1: A 2: B当需要在 Julia 中运行 shell 命令时,先试试复制粘贴。Julia 会先显示出来命令,可以据此检查内插是否正确,再去运行命令。管道Shell 元字符,如 |, &, 及 > 在 Julia 倒引号语法中并是不特殊字符。倒引号中的管道符仅仅是文本化的管道字符 “|” 而已: julia> run(`echo hello | sort`) hello | sort在 Julia 中要想构造管道,应在 Cmd 间使用 |> 运算符: julia> run(`echo hello` |> `sort`) hello继续看个例子: julia> run(`cut -d: -f3 /etc/passwd` |> `sort -n` |> `tail -n5`) 210 211 212 213 214它打印 UNIX 系统五个最高级用户的 ID 。 cut, sort 和 tail命令都作为当前 julia 进程的直接子进程运行,shell 进程没有介入。Julia 自己来设置管道并连接文件描述符, 这些工作通常由 shell 来完成。也因此, Julia 可以对子进程实现更好的控制, 也可以实现 shell 不能实现的一些功能. 值得注意的是, |> 仅仅是重定向了 stdout. 使用 .> 来重定向 stderr.Julia 可以并行运行多个命令: julia> run(`echo hello` & `echo world`) world hello输出顺序是非确定性的。两个 echo 进程几乎同时开始,它们竞争 stdout 描述符的写操作,这个描述符被两个进程和 julia 进程所共有。使用管道,可将这些进程的输出传递给其它程序: julia> run(`echo world` & `echo hello` |> `sort`) hello world来看一个复杂的使用 Julia 来调用 perl 命令的例子: julia> prefixer(prefix, sleep) = `perl -nle '$|=1; print "'$prefix' ", $_; sleep '$sleep';'` julia> run(`p

[1] [2]  下一页


Julia 运行外部程序