Forcelle% x di Ruby su Linux a 64 bit, ma non su 32 e solo con sintassi specifica

StackOverflow https://stackoverflow.com/questions/214205

  •  03-07-2019
  •  | 
  •  

Domanda

Ecco un po 'di codice Ruby:

puts %x{ pstree #{$} }   # never forks
puts %x{ pstree '#{$}' } # forks on amd64 only

Su Ubuntu Dapper a 32 bit, ottengo questo output:

t.rb---pstree
t.rb---pstree

Il che ha senso per me. Ma su Ubuntu Hardy a 64 bit, ottengo questo:

t.rb---sh---pstree
t.rb---pstree

Quello che viene mostrato qui è che le forcelle Ruby prima di essere eseguite in uno dei casi. Quando inserisco il codice in un file e lo eseguo sotto strace -fF, sembra che su Hardy a 64 bit chiama clone () (come fork () ) prima execve () , mentre su Dapper a 32 bit non fa nulla del genere.

Le mie versioni di Ruby sono:

ruby 1.8.4 (2005-12-24) [i486-linux]
ruby 1.8.6 (2007-09-24 patchlevel 111) [x86_64-linux]

Dovrei provare a mixare & amp; interpreti corrispondenti e amp; Sistema operativo & amp; parole di più dimensioni, ma in questo momento non è facile poiché non gestisco queste macchine. Forse qualcuno di voi può dirmi qual è la differenza anche tra questi comandi sul sistema a 64 bit, figuriamoci perché funzionano allo stesso modo su quello a 32 bit.

È stato utile?

Soluzione

Ruby esegue l'espansione della shell quando% x viene utilizzato con un singolo argomento (come stai facendo).

Ecco la mia ipotesi su cosa sta succedendo:

Ruby analizza il comando per determinare se ci sono caratteri speciali che potrebbero comportare la necessità di eseguire l'espansione della shell, in tal caso chiama la shell per farlo. Nel secondo esempio le virgolette singole sono sufficienti per far sì che Ruby voglia chiamare la shell per fare l'espansione, quindi il fork. Nel primo esempio, Ruby può determinare che l'espansione della shell non è necessaria poiché il comando non contiene caratteri speciali (dopo l'espansione variabile), quindi nessun fork. La differenza tra le due versioni probabilmente ha a che fare con un cambiamento interno nel modo in cui ruby ??cerca di determinare se è necessaria l'espansione della shell. Ottengo un fork per il secondo esempio su ruby ??1.8.5 su una macchina a 32 bit.

[EDIT]

Ok, ho dato un'occhiata al codice sorgente per ruby ??1.8.4 e 1.8.6 ed entrambe le versioni usano gli stessi criteri per determinare se chiamare una shell per eseguire l'espansione della shell, se esiste uno dei seguenti caratteri nella riga di comando la shell verrà invocata quando viene fornito un argomento su% x:

*?{}[]<>()~&|\\$;'`"\n

Ruby in realtà chiama la shell in entrambi i casi (nell'esempio che contiene le virgolette), il motivo per cui stai vedendo output diversi da pstree è dovuto alle differenze nel sh comando sui diversi computer, uno chiama fork , l'altro no. Per vederlo da solo, esegui questo comando su entrambe le macchine:

/bin/sh -c "pstree $"

Questo è il comando che Ruby sta usando per eseguire pstree nell'esempio con virgolette su entrambe le macchine. Dovresti vedere bash --- pstree sul computer a 32 bit e bash --- sh --- pstree sull'altro.

Quindi ora sono curioso, cosa ti ha portato a scoprire questa differenza e sta causando un problema?

Altri suggerimenti

Ho attraversato questa situazione sviluppando un lavoro di processore asincrono che ha una serie di sottoprocessi (fork), ed è successo quando il master era in primo piano e ha ricevuto un SIGINT.

Corro: inserisce " il risultato è% (monster-delayed job) "

e l'output era solo: " il risultato è "

  • Sì, sono " trap " SIGINT nel master

Andre

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top