Quando utilizzare ciascun metodo per avviare un sottoprocesso in Ruby

1. `` The Backtick

  • definito nel kernel

1. a) %x{} Percent X <sintassi alternativa per The Backtick

  • definito in parse.y, vedi discussione

2. system()

  • Kernel del sistema #

3. fork()

  • Forcella # kernel, fork # processo

4. open()

  • apri una pipa
  • Kernel # aperto

4.a. IO.popen() <si comporta come open()

  • apri una pipa
  • IO # popen

4.b. open("|-")

  • forchetta a un tubo

4.C. IO.popen("-") <si comporta come open("|-")

  • forchetta a un tubo
  • vedere la discussione

5. Open3.popen3()

  • require 'open3'
  • stdlib Open3

6. PTY.spawn()

  • require 'pty'
  • stdlib PTY

7. Shell.transact()

  • require 'shell'
  • Shell stdlib

Quando si dovrebbe abbandonare il fidato back-tick per uno dei metodi più complessi?

Modifica 1. Grande grazie ad Avdi Grimm per i suoi post che descrivono l’utilizzo di esempio di ciascun metodo: # 1 (& gist ); # 2 (& gist ); # 3 .

Sono risorse fantastiche per rispondere come , ma non sono composte in modo esplicito per rispondere quando ciascuna deve essere usata o perché , e in quanto tale IMHO non sono risposte complete a questa domanda.

  1. utilizzare i backtick quando si desidera catturare facilmente l’output di un programma in una variabile. probabilmente lo vuoi usare solo per programmi a esecuzione ridotta, perché questo si bloccherà.

  2. system è conveniente in due casi diversi:

    un. Si dispone di un programma a esecuzione prolungata e si desidera che l’output venga stampato mentre viene eseguito (ad es. system("tar zxvf some_big_tarball.tar.gz") )

    b. system può bypassare l’espansione della shell come exec (confronta l’output del system "echo *" e il system "echo", "*" )

    blocchi di sistema fino all’uscita dal sottoprocesso.

  3. fork ha anche un paio di casi d’uso diversi:

    un. Si desidera eseguire un codice ruby in un processo separato (ad es. fork { .... }

    b. Si desidera eseguire un processo figlio (o un programma diverso) senza bloccare il progresso del fork { exec "bash" } script fork { exec "bash" } .

    fork è tuo amico se vuoi demonizzare il tuo programma.

  4. IO.popen è utile quando è necessario interagire con lo standard out e lo standard di un programma. Nota che non acquisisce errori standard, quindi devi redirect quello con 2>&1 se ti interessa.

  5. popen3 fornisce un descrittore di file separato per errore standard (per quando è necessario acquisirlo separatamente dallo standard)

  6. PTY.spawn è necessario quando si desidera che il programma generato si comporti come si sta eseguendo dal terminale. Guarda la differenza di grep --color=auto pat file quando viene generato con system vs PTY.spawn

Ecco un diagramma di stream basato su questa risposta . Vedi anche, usando lo script per emulare un terminale .

inserisci la descrizione dell'immagine qui

Dai un’occhiata a questa serie di articoli:

  • Una dozzina (o quasi) modi per avviare i processi secondari in Ruby: Parte 1
  • Una dozzina (o così) modi per avviare i processi secondari in Ruby: Parte 2
  • Una dozzina (o così) modi per avviare i processi secondari in Ruby: Parte 3