以下翻译自:Rdocumentation:system {base}
函数system
的作用是,调用由参数command
指定的操作系统命令。
system(command, intern = FALSE,
ignore.stdout = FALSE, ignore.stderr = FALSE,
wait = TRUE, input = NULL, show.output.on.console = TRUE,
minimized = FALSE, invisible = TRUE)
参数 | 说明 |
---|---|
command | 待执行的系统命令,是一个字符串 |
intern | 逻辑值(非NA 值),声明是否将执行系统命令得到的结果,作为R的字符向量输出 |
ignore.stdout, ignore.stderr | 逻辑值(非NA 值),声明是否忽略stdout 或stderr 信息 |
wait | 逻辑值(非NA 值),声明R解释器是否需要等待系统命令执行完毕,还是可以异步(不同时)执行。如果参数intern = TRUE ,那么参数wait将会被忽略(R解释器会一直等到系统命令执行完成,即wait总是等于TRUE) |
input | 如果提供了一个字符向量,则会按照每行一个字符串的格式,将其复制到一个临时文件中,并将command 的标准输入形式重定向到该文件 |
show.output.on.console | 逻辑值(非NA 值),声明是否将执行系统命令得到的结果,显示在R控制台中(不是使用Rterm ,除非参数wait = FALSE ,否则Rterm是将结果显示在终端) |
minimized | 逻辑值(非NA 值),声明是否将CMD窗口最小化显示 |
invisible | 逻辑值(非NA 值),声明是否在屏幕上显示CMD窗口 |
【注】:show.output.on.console
、minimized
、invisible
都是在Windows系统下才能使用的参数,在本平台使用将会被忽略,并抛出警告。
多年来,这个接口已经变得相当复杂:请参阅system2,以获得更适合新代码的便携式和灵活接口。
command
将被解析为一个命令加上由空格分隔的参数。所以如果命令的路径(或单个参数,如文件路径)包含空格,则必须由(例如)shQuote引用。在Windows上只允许使用双引号:详见示例。(注意:Windows路径名不能包含双引号,所以我们不需要担心转义嵌入的引号。)
command
必须是可执行文件(扩展名为.exe
,.com
)或批处理文件(扩展名为.cmd
和.bat
):如果没有提供,则会依次尝试这些扩展名。这意味着不能使用重定向、管道、DOS内部命令等:如果你想传递一个shell命令行,请参阅shell。
command
的搜索路径可能与系统有关:它将包含Rbin
目录、在PATH
之前的工作目录和Windows系统目录。类似Unix的操作系统会将命令行传递给shell(通常是/bin/sh
,而POSIX需要这个shell),所以command
可以是shell认为可执行的任何东西,包括shell脚本,它可以包含多个命令,以;
区分开。
在Windows系统中,函数system
不会使用shell,有另外一个独立的函数shell
可以将命令行传递给shell。
若intern = TRUE
,则会使用popen
来调用命令,并将结果以R的字符向量形式逐行输出;若intern = FALSE
,则使用C函数system
来调用命令。
wait
是通过在命令后面附加&
得以执行的:这在原理上是依赖于shell的,也是POSIX的要求,并得到了广泛支持。
前两个参数之后的其他参数在排序时,顺序会不时发生变化:因此建议对首个参数之后的所有参数进行命名。
用函数system
来确定一个命令是否可以运行有很多缺陷,推荐使用Sys.which。
若intern = TRUE
,命令结果是一个字符向量,按照每个字符串一行的格式将其输出。(输出结果超过8095字节的行将被拆分)如果命令无法运行,则会生成错误提示(R error)。在Rgui控制台中,除非设定ignore.stderr = TRUE
,否则 intern = TRUE
会捕获stderr
信息。如果运行command
,但得到一个非零的退出状态,则将抛出一个警告,并在结果属性status
中提示:属性errmsg
可能也适用。
若intern = FALSE
,给定invisible = TRUE
,返回值将是一个错误代码(0
代表成功)(因此需要设置显式输出)。若命令始终无法运行,返回值是127
。此外,若wait = TRUE
,执行命令后返回的值是退出状态,若wait = FALSE
,返回值为0
(常规成功值)。某些Windows命令会返回超出范围的状态值(例如-1),因此只使用该值的后16位。
若intern = FALSE
,wait = TRUE
,show.output.on.console = TRUE
,命令(控制台应用程序)输出的stdout
和stderr
信息将会呈现在R控制台(Rgui
)或正在运行R的窗口(Rterm
)(除非ignore.stdout = TRUE
或ignore.stderr = TRUE
)
并非所有的Windows可执行文件都能正确遵循输出的重定向,或者只能满足从Rterm
等控制台应用程序(而不是从Rgui
)执行重定向:例如,fc.exe
就是其中之一,但我们最近取得了更大的成功。
对于GUI,当intern = FALSE
时,发送到stdout
或stderr
的输出结果是接口特定的,如果这些消息出现在GUI控制台中,将很不安全。(在macOS的GUI控制台上确实是如此执行的,但在其他一些控制台上没有这么做)
对于命令行R,除非设置ignore.stderr = TRUE
,否则写入stderr
的错误消息将被发送到终端,可以通过如下代码(在最有可能的shell中)获得消息内容:
system("some command 2>&1", intern = TRUE)
准确地说,不论Rgui
或Rterm
是否正在使用,不论控制台命令或GUI应用程序是否正在运行,用户可见的取决于可选参数。
默认情况下,在命令结束并显示输出前,前端不会显示任何信息。
对于控制台命令Rgui
会打开一个新的控制台,因此若设置invisible = FALSE
,在命令持续期间,会出现一个命令窗口。对于Rterm
,只有当wait = FALSE
和invisible = FALSE
时,才会出现一个单独的命令窗口。
除非invisible = FALSE
,否则GUI应用程序不会在任何前端显示。
可以通过键盘操作(Rgui
中使用Esc键,或Rterm
中使用Ctrl+C)或在Rgui菜单里,中断正在运行(等待中)的命令:这个操作会将控制权返回给R控制台。R会试图完全中断该过程,但可能需要强制终止,并有可能丢失未保存的工作等。
要求用户从Rgui
输入设置intern = TRUE
或设置show.output.on.console = TRUE
的控制台应用程序是不起作用的,无须尝试运行。
Windows和类Unix操作系统的启动过程基本上是不同的,在R函数所在的高级操作系统函数中也是如此。所以在操作系统之间,函数system
的表现有许多不同也不足为奇。为满足程序员的便利需求,本节总结了较为重要的部分。
最重要的不同之处是,在类Unix系统中,函数system
会启动一个(稍后将)运行command
的shell。而在Windows系统中,则是直接运行命令——用函数shell
通过一个shell界面运行commad
(默认情况下Windows shell是cmd.exe
,其与POSIX shell有很大区别)。
这意味着,重定向或管道命令在函数system
中不起作用(重定向有时可以运行,但发生过安装完Windows安全补丁后就停止运行的情况),Windows系统上必须使用函数system2
(或函数shell
)
当未捕获信息时,stdout和stderr会如何变化,取决于R是如何运行的:Windows系统下的批处理命令就像类Unix系统一样,但在Windows GUI中信息通常会丢失。除非设置ignore.stderr = TRUE
,否则在Windows GUI控制台的运行中,system(intern = TRUE)
将会捕获stderr
信息
错误(error)提示在细节方面有所不同(不同的R版本之间也不同)
command
的引用约定各不相同,但shQuote
是一个便携式接口
参数show.output.on.console
、 minimized
、invisible
仅在Windows系统下使用(这些参数与Windows系统的Rgui关系最为密切)
查看非原始的接口:shell或shell.exec。查看man system
和man sh
了解这个过程如何在操作系统上实现。
查看.Platform了解平台特定的变量。
使用pipe建立管道连接。
# 使用-F标记列出当前目录中的所有文件
system("ls -F")
# t1是一个字符向量,其中各个元素分别对应于who输出的每一行(假设该平台存在对象who)
t1 <- try(system("who", intern = TRUE))
try(system("ls fizzlipuzzli", intern = TRUE, ignore.stderr = TRUE))
# 返回结果长度为0,因为文件不存在,并会抛出警告
# 启动一个编辑器, 等待其退出
## Not run: system("notepad myfile.txt")
# 打开最常用的shell:
## Not run: system(Sys.getenv("COMSPEC"))
## Not run:
## 注意如下两种引用方式:
system(paste('"c:/Program Files/Mozilla Firefox/firefox.exe"',
'-url cran.r-project.org'), wait = FALSE)
## End(Not run)