Raffiniert ist Python, aber boshaft is Er Nicht.
Python è sottile, ma non malizioso.
(A. Einstein)
Come si farebbe se non esistessero le variabili d’ambiente (environment variables)? Sono talmente utili che esistono anche nei sistemi operativi più rozzi e truzzi, tipo Windoze.
E Python, il migliore dei linguaggi possibili ha naturalmente un modulo per il loro supporto (c’è sempre un modulo che fa quello che vi serve in Python).
Proviamo a metterle in opera. La prima versione è elementare
import os
print os.path.expandvars("$HOME")
e lanciandolo otteniamo:
* : /media/algol/lab/OKp/variabili $ python h.py /home/n1n0 * : /media/algol/lab/OKp/variabili $
tutto Ok, funziona come previsto.
Ma HOME è una variabile predefinita, noi vogliamo definire le nostre variabili e usare quelle.
Con il comando
export ATH_H=/media/algol/w3/harbor
definiamo la variabile ATH_H e la rendiamo globale, possiamo testarla con
* : /media/algol/lab/OKp/variabili $ printenv ATH_H /media/algol/w3/harbor * : /media/algol/lab/OKp/variabili $
o anche con
* : /media/algol/lab/OKp/variabili $ echo $ATH_H /media/algol/w3/harbor * : /media/algol/lab/OKp/variabili $
Modifichiamo il nostro script Python così
import os
print os.path.expandvars("$HOME")
print os.path.expandvars("$ATH_H")
ed eseguiamo
* : /media/algol/lab/OKp/variabili $ python v0.py /home/n1n0 /media/algol/w3/harbor * : /media/algol/lab/OKp/variabili $
OK!
Ma se chiudiamo il terminale che abbiamo usato finora e ne apriamo un altro avremo una sorpresa:
* : /media/algol/lab/OKp/variabili $ echo $ATH_H * : /media/algol/lab/OKp/variabili $ *
la nostra variabile è sparita. Per averla sempre a disponibile dobbiamo mettere la sua definizione in un file di configurazione. La prima cosa che viene in mente è ~/.bashrc, è un file di testo e potete modificarlo con il vostro editor preferito: gedit, vi o …
Per rendere effettive la modifica dovete rilogarvi o riavviare il ‘puter.
Finora abbiamo lavorato nel terminale, niente finestre, ma adesso…
#!/usr/bin/python
# -*- coding: utf-8 -*-
import wx
import os
class MyFrame(wx.Frame):
def __init__(self, parent, id):
wx.Frame.__init__(self, parent, id, size = (200, 60),
title = "$var", style = wx.wx.CAPTION | wx.CLOSE_BOX)
res = "%s\n%s" %(os.path.expandvars("$HOME"),
os.path.expandvars("$ATH_H"))
labres = wx.StaticText(self, wx.ID_ANY, label = res)
color = 'blue'
labres.SetForegroundColour(color)
labres.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD))
class MyApp(wx.App):
def OnInit(self):
frame = MyFrame(None, -1)
frame.Show(True)
self.SetTopWindow(frame)
return True
app = MyApp(redirect = 0)
app.MainLoop()
Proviamo a eseguirla
* : /media/algol/lab/OKp/variabili $ python win.py

Non va! La variabile HOME, predefinita, viene vista, la nostra no.
Una googlata per “environment variables” ci porta a questa pagina che ci consiglia di definire le nostre variabili in ~/.pam_environment
This file is specifically meant for setting a user’s environment. It is not a script file, but rather consists of assignment expressions, one per line.
E non c’è bisogno di usare export. Io l’ho fatto così:
ATH_H=/media/algol/w3/harbor ATH_APPS=$HOME/apps ATH_DISK=/media/algol ATH_LAB=$ATH_DISK/lab ATH_PFIL=$ATH_APPS/pfil ATH_U80D=$ATH_APPS/u80d
Al solito occorre riavviare, dopo otteniamo:
* : /media/algol/lab/OKp/variabili $ set | grep ATH_ ATH_APPS='$HOME/apps' ATH_DISK=/media/algol ATH_H=/media/algol/w3/harbor ATH_LAB='$ATH_DISK/lab' ATH_PFIL='$ATH_APPS/pfil' ATH_U80D='$ATH_APPS/u80d' * : /media/algol/lab/OKp/variabili $
e se rilanciamo lo script avremo

OK? OK!
(sì ho barato: ho allungato la finestra altrimenti la scritta andava a capo, perdono)
Possiamo anche creare un lanciatore

Mi restano due dubbi che espongo brevemente di seguito.
Variabili definite in funzione di variabili
Esaminando la definizione
ATH_LAB=$ATH_DISK/lab
dipende da
ATH_DISK=/media/algol
e testandola si ottiene:
* : /media/algol/lab/OKp/variabili $ printenv ATH_DISK /media/algol * : /media/algol/lab/OKp/variabili $ printenv ATH_LAB $ATH_DISK/lab * : /media/algol/lab/OKp/variabili $
non va. Con uno scriptino come questo
import os
def true_val(st):
while st.find('$') >= 0:
st = os.path.expandvars(st)
print '*', st
return st
print true_val('sprint')
print true_val('$HOME')
print true_val('$ATH_DISK')
print true_val('$ATH_LAB')
si ottiene il valore esatto ma probamilmente è ‘na gran strunzata (cit.)
Riguardo Einstein
A me sembra che il problema non sia tanto di Python quanto di Gnome. Ma chi ha il coraggio di contraddirlo.
Non ho al momento la possibilità di provarlo con Windows, appena posso verifico cosa capita da quelle parti.

Commenti
Commenti:
per rendere effettiva una variabile d’ambiente in .bashrc, si può anche lanciare
$ source .bashrc
oppure chiudere il terminale e aprirne un altro, senza bisogno di riavviare. E’ vero che quelle variabili non vengono viste dall’ambiente grafico, che parte prima della shell.
Secondo: Probabilmente non ti va per mancanza di export. La gestione delle variabili di ambiente è specifica di ogni shell, ecco perché con lo script python ti va (espande) e con la shell non espande.
Prova con
printenv $ATH_LAB
dovrebbe espandere correttamente (spero). (io non uso .pam_environment)
Sì per il source hai ragione, l’ho dimenticato. Per il resto con bash e Ubuntu vale quanto scritto nel post. Allego un dumpino:
* : ~ $ printenv $ATH_LAB
* : ~ $ set | grep ATH_
ATH_APPS=’$HOME/apps’
ATH_DISK=/media/algol
ATH_LAB=’$ATH_DISK/lab’
ATH_PFIL=’$ATH_APPS/pfil’
ATH_U80D=’$ATH_APPS/u80d’
_=’$ATH_DISK/lab’
* : ~ $ printenv ATH_LAB
$ATH_DISK/lab
* : ~ $ echo $ATH_LAB
$ATH_DISK/lab
* : ~ $
A differenza di echo e dei comandi normali printenv non vuole il $ davanti al nome della variabile.
In effetti, ora che ci penso non ho considerato ` e/o $() ma il post voleva essere elementare e forse sono stato anche troppo prolisso.
Domanda: questo genere di post possono servire? o sono troppo solipsistici?
Trackback
[...] E pensare che anticamente avevo fatto anche un post su questo argomento: Variabili d’ambiente. Python è sottile. [...]
[...] OK. Una variabile settata al volo viene vista normalmente, Python invece è molto più schizzinoso, ne avevo parlato qui. [...]