當前位置: 首頁>>代碼示例 >>用法及示例精選 >>正文


Ruby Process.spawn用法及代碼示例


本文簡要介紹ruby語言中 Process.spawn 的用法。

用法

spawn([env,] command... [,options]) → pid
spawn([env,] command... [,options]) → pid

spawn 執行指定的命令並返回它的 pid。

pid = spawn("tar xf ruby-2.0.0-p195.tar.bz2")
Process.wait pid

pid = spawn(RbConfig.ruby, "-eputs'Hello, world!'")
Process.wait pid

此方法類似於 Kernel#system ,但它不等待命令完成。

父進程應使用 Process.wait 收集其子進程的終止狀態,或使用 Process.detach 記錄對其狀態的不感興趣;否則,操作係統可能會積累僵屍進程。

spawn 有很多選項來指定進程屬性:

env: hash
  name => val : set the environment variable
  name => nil : unset the environment variable

  the keys and the values except for +nil+ must be strings.
command...:
  commandline                 : command line string which is passed to the standard shell
  cmdname, arg1, ...          : command name and one or more arguments (This form does not use the shell. See below for caveats.)
  [cmdname, argv0], arg1, ... : command name, argv[0] and zero or more arguments (no shell)
options: hash
  clearing environment variables:
    :unsetenv_others => true   : clear environment variables except specified by env
    :unsetenv_others => false  : don't clear (default)
  process group:
    :pgroup => true or 0 : make a new process group
    :pgroup => pgid      : join the specified process group
    :pgroup => nil       : don't change the process group (default)
  create new process group: Windows only
    :new_pgroup => true  : the new process is the root process of a new process group
    :new_pgroup => false : don't create a new process group (default)
  resource limit: resourcename is core, cpu, data, etc.  See Process.setrlimit.
    :rlimit_resourcename => limit
    :rlimit_resourcename => [cur_limit, max_limit]
  umask:
    :umask => int
  redirection:
    key:
      FD              : single file descriptor in child process
      [FD, FD, ...]   : multiple file descriptor in child process
    value:
      FD                        : redirect to the file descriptor in parent process
      string                    : redirect to file with open(string, "r" or "w")
      [string]                  : redirect to file with open(string, File::RDONLY)
      [string, open_mode]       : redirect to file with open(string, open_mode, 0644)
      [string, open_mode, perm] : redirect to file with open(string, open_mode, perm)
      [:child, FD]              : redirect to the redirected file descriptor
      :close                    : close the file descriptor in child process
    FD is one of follows
      :in     : the file descriptor 0 which is the standard input
      :out    : the file descriptor 1 which is the standard output
      :err    : the file descriptor 2 which is the standard error
      integer : the file descriptor of specified the integer
      io      : the file descriptor specified as io.fileno
  file descriptor inheritance: close non-redirected non-standard fds (3, 4, 5, ...) or not
    :close_others => false  : inherit
  current directory:
    :chdir => str

cmdname, arg1, ... 表單不使用 shell 。但是,在不同的操作係統上,作為內置命令提供了不同的東西。這方麵的一個例子是 +‘echo’+,它是 Windows 的內置程序,但在 Linux 和 Mac OS X 上是一個普通程序。這意味著 Process.spawn 'echo', '%Path%' 將顯示 %Path% 環境變量的內容Windows,但 Process.spawn 'echo', '$PATH' 打印文字 $PATH

如果一個散列被指定為 env ,則在子進程中 envexec(2) 之前更新環境。如果env 中的一對具有 nil 作為值,則刪除該變量。

# set FOO as BAR and unset BAZ.
pid = spawn({"FOO"=>"BAR", "BAZ"=>nil}, command)

如果一個哈希被指定為 options ,它指定進程組、創建新進程組、資源限製、當前目錄、umask 和子進程的重定向。此外,可以指定清除環境變量。

options 中的 :unsetenv_others 鍵指定清除環境變量,而不是由 env 指定。

pid = spawn(command, :unsetenv_others=>true) # no environment variable
pid = spawn({"FOO"=>"BAR"}, command, :unsetenv_others=>true) # FOO only

options 中的:pgroup 鍵指定一個進程組。對應的值應該是 true、零、正整數或 nil。 true 和 0 使進程成為新進程組的進程領導。非零正整數會導致進程加入提供的進程組。默認值 nil 使進程保持在同一個進程組中。

pid = spawn(command, :pgroup=>true) # process leader
pid = spawn(command, :pgroup=>10) # belongs to the process group 10

options 中的 :new_pgroup 鍵指定將 CREATE_NEW_PROCESS_GROUP 標誌傳遞給作為 Windows API 的 CreateProcessW()。此選項僅適用於 Windows。 true 表示新進程是新進程組的根進程。新進程已禁用 CTRL+C。該標誌對於子進程上的Process.kill(:SIGINT, pid) 是必需的。 :new_pgroup 默認為假。

pid = spawn(command, :new_pgroup=>true)  # new process group
pid = spawn(command, :new_pgroup=>false) # same process group

:rlimit_ foo 鍵指定資源限製。 foo 應該是資源類型之一,例如 core 。對應的值應該是一個整數或具有一個或兩個整數的數組:與 Process.setrlimit 的 cur_limit 和 max_limit 參數相同。

cur, max = Process.getrlimit(:CORE)
pid = spawn(command, :rlimit_core=>[0,max]) # disable core temporary.
pid = spawn(command, :rlimit_core=>max) # enable core dump
pid = spawn(command, :rlimit_core=>0) # never dump core.

options 中的 :umask 鍵指定 umask。

pid = spawn(command, :umask=>077)

:in、:out、:err、整數、 IO 和數組鍵指定重定向。重定向在子進程中映射一個文件說明符。

例如,stderr 可以合並到 stdout 中,如下所示:

pid = spawn(command, :err=>:out)
pid = spawn(command, 2=>1)
pid = spawn(command, STDERR=>:out)
pid = spawn(command, STDERR=>STDOUT)

哈希鍵指定由 spawn.:err, 2 啟動的子進程中的文件說明符,STDERR 指定標準錯誤流(stderr)。

哈希值指定調用 spawn.:out, 1 的父進程中的文件說明符,而 STDOUT 指定標準輸出流 (stdout)。

在上麵的例子中,沒有指定子進程中的標準輸出。所以它是從父進程繼承的。

標準輸入流 (stdin) 可以通過:in、0 和 STDIN 指定。

文件名可以指定為哈希值。

pid = spawn(command, :in=>"/dev/null") # read mode
pid = spawn(command, :out=>"/dev/null") # write mode
pid = spawn(command, :err=>"log") # write mode
pid = spawn(command, [:out, :err]=>"/dev/null") # write mode
pid = spawn(command, 3=>"/dev/null") # read mode

對於 stdout 和 stderr(以及它們的組合),它以寫入模式打開。否則使用讀取模式。

為了明確指定文件創建的標誌和權限,使用數組代替。

pid = spawn(command, :in=>["file"]) # read mode is assumed
pid = spawn(command, :in=>["file", "r"])
pid = spawn(command, :out=>["log", "w"]) # 0644 assumed
pid = spawn(command, :out=>["log", "w", 0600])
pid = spawn(command, :out=>["log", File::WRONLY|File::EXCL|File::CREAT, 0600])

該數組指定文件名、標誌和權限。標誌可以是字符串或整數。如果標誌被省略或為零,則假定為 File::RDONLY。權限應該是一個整數。如果權限被省略或為零,則假定為 0644。

如果將 IO 和整數數組指定為哈希鍵,則所有元素都將被重定向。

# stdout and stderr is redirected to log file.
# The file "log" is opened just once.
pid = spawn(command, [:out, :err]=>["log", "w"])

合並多個文件說明符的另一種方法是 [:child, fd]。 [:child, fd] 表示子進程中的文件說明符。這與 fd 不同。例如:err=>:out 表示將子stderr 重定向到父stdout。但是:err=>[:child,:out] 表示將子標準錯誤重定向到子標準輸出。如果標準輸出在子進程中被重定向,它們會有所不同,如下所示。

# stdout and stderr is redirected to log file.
# The file "log" is opened just once.
pid = spawn(command, :out=>["log", "w"], :err=>[:child, :out])

[:child, :out] 可用於將 stderr 合並到 IO.popen 中的 stdout 中。在這種情況下, IO.popen 將標準輸出重定向到子進程中的管道,並且 [:child, :out] 指的是重定向的標準輸出。

io = IO.popen(["sh", "-c", "echo out; echo err >&2", :err=>[:child, :out]])
p io.read #=> "out\nerr\n"

options 中的:chdir 鍵指定當前目錄。

pid = spawn(command, :chdir=>"/var/tmp")

spawn 默認關閉所有非標準的未指定說明符。 “standard” 說明符是 0、1 和 2。此行為由:close_others 選項指定。:close_others 不影響僅在明確指定:close 時關閉的標準說明符。

pid = spawn(command, :close_others=>true)  # close 3,4,5,... (default)
pid = spawn(command, :close_others=>false) # don't close 3,4,5,...

:close_others 對於 spawn 和 IO.popen 默認為 false。

請注意,無論:close_others 選項如何,已設置close-on-exec 標誌的fds 都將關閉。

所以 IO.pipe 和 spawn 可以用作 IO.popen

# similar to r = IO.popen(command)
r, w = IO.pipe
pid = spawn(command, :out=>w)   # r, w is closed in the child process.
w.close

:close 被指定為單獨關閉 fd 的哈希值。

f = open(foo)
system(command, f=>:close)        # don't inherit f.

如果需要繼承文件說明符,可以使用io=>io。

# valgrind has --log-fd option for log destination.
# log_w=>log_w indicates log_w.fileno inherits to child process.
log_r, log_w = IO.pipe
pid = spawn("valgrind", "--log-fd=#{log_w.fileno}", "echo", "a", log_w=>log_w)
log_w.close
p log_r.read

也可以交換文件說明符。

pid = spawn(command, :out=>:err, :err=>:out)

哈希鍵指定子進程中的文件說明符。哈希值指定父進程中的文件說明符。所以上麵指定交換標準輸出和標準錯誤。在內部,spawn 使用額外的文件說明符來解析這種循環文件說明符映射。

有關標準 shell ,請參見 Kernel.exec

相關用法


注:本文由純淨天空篩選整理自ruby-lang.org大神的英文原創作品 Process.spawn。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。