2009-02-06 31 views
9

In Perl, ho bisogno di leggere l'ambiente di altri processi.C'è un modo per leggere le variabili di ambiente di altri processi usando Perl e in un ambiente Linux o Solaris?

  • Lo script è in esecuzione con radice privilegi.
  • Lo script sarà esecuzione in Linux e Solaris.
  • vorrei una soluzione che è in gran parte indipendente dalla piattaforma, almeno tra Linux e Solaris. In Linux, esaminare/env/< proc_id>/environ può ottenere la risposta.
  • Vorrei evitare di dover forchetta. Ho già una soluzione forking "/ usr/ucb/ps -auxwwwe $ pid"

Qualche idea?

risposta

7

Per Solaris, è possibile provare il procfs module from CPAN. Anche se questo modulo sembra ancora molto giovane, questa citazione suona speranza:

Brian Farrell ha inviato una patch molto utile che gestisce ispezione del argv e l'ambiente dei processi diversi dal processo attualmente in esecuzione.

Immagino che questo sia probabilmente solo l'ambiente iniziale (proprio come il file environ sotto linux), ma quello sembra essere quello che vuoi?

Altrimenti, anche se ti vedo dire che non vuoi biforcarti, una soluzione semplice probabilmente farebbe girare a circa 20 righe di C per produrre un piccolo programma che sputa l'ambiente su Solaris esattamente come l'equivalente del Linux environ file. Ho già qualcosa di molto simile in C. Se sei interessato, posso postarlo.

EDIT (dopo aver letto OpenSolaris pargs.c): il buffer di ambiente viene riallocato in Solaris quando l'ambiente cambia, quindi il puntatore di psinfo potrebbe non essere valido. Per una soluzione a prova di proiettile, devi dare la caccia a _environ. Probabilmente è molto più fastidioso di quello che ti serve ... pargs -e <pid> potrebbe essere un alterativo più bello per UCB ps(1) se si va sul bivio, però.

+1

per essere chiari: pargs -e è la strada da percorrere (avvolgere questo all'interno di una chiamata di sistema perl) – PaulS

12

In linux sembra che il /proc/<pid>/environ psuedofiles contengono la variabile environ passato quando è stato creato il processo. Se hai un permesso sufficiente, puoi leggerli.

Essi non sembrano tenere traccia delle modifiche nell'ambiente processi dopo il lancio.

Ciò suggerisce che si dovrebbe disect il dump della memoria dei processi per ottenere quello che stai chiedendo.

Tricky.

+0

Heh. Sembra che in realtà non abbia letto la domanda. Scusate. – dmckee

+0

Il file system Solaris/proc (Solaris 10) non sembra includere anche l'ambiente originale. –

+0

@ Jonathan, dare un'occhiata al file/proc/pid/psinfo e vedere struct psinfo da . Il campo pr_envp è l'ambiente iniziale. –

5

La prima cosa che mi viene in mente è usare GDB per collegarsi al processo in questione e quindi chiedere a GDB di ottenere l'ambiente per tu. Puoi farlo con il comando "show environment" nella shell GDB .

Sembra che ci sia un modulo Perl che può fare questo per voi, Devel::GDB. Non ho ancora provato lo strumento , ma sembra una semplice questione di programmazione su creare l'oggetto Devel :: GDB, connettersi al processo che si desidera controllare , inviare il comando "show environment", quindi analizzare lo risultati.

Devo dire però ... quando la soluzione è così complicata, è probabile che tu stia facendo qualcos'altro che non va, . Perché è necessario l'ambiente per un processo casuale, comunque?

+0

Preventivo: Perché hai bisogno dell'ambiente per un processo casuale, comunque? Questo è parte di uno script che raccoglie informazioni sui processi in esecuzione nel sistema. I dati vengono salvati per essere analizzati in seguito. –

+0

mostra l'ambiente mostra l'ambiente di gdb, non il processo a cui è collegato. Dal manuale gdb: "Stampa il valore della variabile di ambiente varname da dare al tuo programma quando inizia." In altre parole, l'ambiente di presentazione è utile se stai pianificando di avviare un programma, ma non è utile per informarti sull'ambiente di un programma a cui ti colleghi. Correggimi se ho torto, ma i miei test e la lettura del manuale suggeriscono che questa risposta è completamente errata. –

2

Se ps può farlo, come dici tu, allora la tua risposta può essere trovata da qualche parte nel codice sorgente di ps. Ciò eviterebbe la generazione di un nuovo processo.

8

Il pacchetto GNU "binutils" include un'utilità CLI denominata strings. Vedi http://www.gnu.org/software/binutils/ per maggiori informazioni.

strings /proc/pid/environ - stampa una bella lista delle variabili di ambiente come env.

+1

Sono anche venuto qui cercando una risposta specifica perl non perl. '/ proc/$$/environ' è un elenco nullo-separato di stringhe' KEY = value' (ho scoperto chiedendo 'xxd/proc/$$/environ' ma probabilmente è documentato da qualche parte). Puoi trasformarlo in qualcosa di più leggibile con solo strumenti POSIX standard. Basta usare 'cat/proc/$$/environ | tr '\ 0' '\ n''. – alsuren

+0

@alsuren Grazie. Che funzioni. Sia xxd sia l'uso di tr per correggere l'output sono abbastanza utili. –

0

Su Linux può essere sufficiente risolvere il collegamento simbolico /proc/[pid]/cwd, vedere procfs(5).