Domanda

Su Unix, c'è un modo in cui un processo può cambiare le variabili d'ambiente di un altro (supponendo che siano tutte eseguite dallo stesso utente)? Una soluzione generale sarebbe la migliore, ma in caso contrario, che dire del caso specifico in cui uno è figlio dell'altro?

Modifica: che ne dici di via gdb?

È stato utile?

Soluzione

Via gdb:

(gdb) attach process_id

(gdb) call putenv ("env_var_name=env_var_value")

(gdb) detach

Questo è piuttosto un brutto hack e dovrebbe essere fatto solo nel contesto di uno scenario di debug, ovviamente.

Altri suggerimenti

Probabilmente puoi farlo tecnicamente (vedi altre risposte), ma potrebbe non aiutarti.

La maggior parte dei programmi prevede che non sia possibile modificare l'ambiente dopo l'avvio, quindi la maggior parte probabilmente leggerà solo gli argomenti a cui è interessato all'avvio e inizializzarsi in base a quello. Quindi cambiarli in seguito non farà differenza, poiché il programma non li rileggerà mai.

Se lo hai pubblicato come problema concreto, probabilmente dovresti adottare un approccio diverso. Se fosse solo per curiosità: bella domanda :-).

Sostanzialmente, no. Se si disponevano di privilegi sufficienti (root o successivi) e si cercava in giro / dev / kmem (memoria del kernel) e si sono apportate modifiche all'ambiente del processo e se il processo ha effettivamente fatto nuovamente riferimento alla variabile di ambiente in seguito (ovvero, il processo non avevo già preso una copia di env var e non usava solo quella copia), quindi forse, se eri fortunato e intelligente, e il vento soffiava nella giusta direzione, e la fase della luna era corretta, forse, potresti ottenere qualcosa.

Citando Jerry Peek:

  

Non puoi insegnare a un vecchio cane nuovi trucchi.

L'unica cosa che puoi fare è cambiare la variabile d'ambiente del processo figlio prima di avviarlo: ottiene la copia dell'ambiente genitore, mi dispiace.

Vedi http://www.unix.com.ua/orelly /unix/upt/ch06_02.htm per i dettagli.

Solo un commento sulla risposta sull'uso di / proc. In linux / proc è supportato ma, non funziona, non puoi cambiare il file / proc / $ {pid} / environment , anche se sei root: è assolutamente di sola lettura.

Potrei pensare al modo piuttosto inventato per farlo, e non funzionerà per processi arbitrari.

Supponi di scrivere la tua libreria condivisa che implementa 'char * getenv'. Quindi, imposta 'LD_PRELOAD' o 'LD_LIBRARY_PATH' env. varia in modo che entrambi i processi vengano eseguiti con la libreria condivisa precaricata.

In questo modo, avrai essenzialmente un controllo sul codice della funzione 'getenv'. Quindi, potresti fare ogni sorta di brutti scherzi. Il tuo 'getenv' potrebbe consultare il file di configurazione esterno o il segmento SHM per valori alternativi di env vars. Oppure potresti fare regexp cerca / sostituisci sui valori richiesti. Oppure ...

Non riesco a pensare a un modo semplice per farlo per processi in esecuzione arbitrari (anche se sei root), a meno di riscrivere il linker dinamico (ld-linux.so).

O fai in modo che il tuo processo aggiorni un file di configurazione per il nuovo processo e poi:

  • esegui un kill -HUP sul nuovo processo per rileggere il file di configurazione aggiornato, oppure
  • fare in modo che il processo controlli gli aggiornamenti del file di configurazione ogni tanto. Se vengono rilevate modifiche, rileggere il file di configurazione.

Non per quanto ne so. In realtà stai cercando di comunicare da un processo a un altro che richiede uno dei metodi IPC (memoria condivisa, semafori, socket, ecc.). Dopo aver ricevuto i dati con uno di questi metodi, è possibile impostare variabili di ambiente o eseguire altre azioni in modo più diretto.

Se il tuo unix supporta il filesystem / proc, allora è banale LEGGERE env: puoi leggere l'ambiente, la linea di comando e molti altri attributi di qualsiasi processo che possiedi in quel modo. Cambiandolo ... Beh, posso pensare a un modo, ma è un'idea MALE.

Il caso più generale ... Non lo so, ma dubito che ci sia una risposta portatile.

(Modificato: la mia risposta originale presupponeva che l'OP volesse LEGGERE l'ENV, non modificarlo)

UNIX è pieno di comunicazione tra processi. Controlla se l'istanza di destinazione ne ha. Dbus sta diventando uno standard in "desktop" IPC.

Cambio le variabili d'ambiente all'interno di Awesome window manager usando awesome-client con is Dbus " mittente " del codice lua.

Non una risposta diretta ma ... Raymond Chen aveva una logica [basata su Windows] intorno a questo solo l'altro giorno : -

  

... Anche se ci sono certamente modi non supportati per farlo o modi che funzionano con l'assistenza di un debugger, non c'è nulla che sia supportato per l'accesso programmatico a un'altra riga di comando di processo, almeno niente fornito dal kernel. ...

     

Che non esiste una conseguenza del principio di non tenere traccia delle informazioni di cui non hai bisogno. Il kernel non ha bisogno di ottenere la riga di comando di un altro processo. Prende la riga di comando passata alla funzione CreateProcess e la copia nello spazio degli indirizzi del processo avviato, in una posizione in cui la funzione GetCommandLine può recuperarla. Una volta che il processo può accedere alla propria riga di comando, le responsabilità del kernel sono terminate.

     

Poiché la riga di comando viene copiata nello spazio degli indirizzi del processo, il processo potrebbe persino scrivere nella memoria che contiene la riga di comando e modificarla. Se ciò accade, la riga di comando originale viene persa per sempre; l'unica copia conosciuta è stata sovrascritta.

In altre parole, tali servizi del kernel sarebbero

  • difficile da implementare
  • potenzialmente un problema di sicurezza

Tuttavia il motivo più probabile è semplicemente che ci sono casi d'uso limitati per una tale struttura.

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