L'interfaçage avec le système d'exploitation et Common Lisp dépend encore beaucoup de votre distribution Lisp. Il n'est donc pas facile de trouver une bonne bibliothèque qui fonctionne dans toutes les distributions CL.
Je vous recommande de travailler avec UIOP, qui est livré avec ASDF 3 et plus et qui est la meilleure bibliothèque pour travailler avec l'OS dans Common Lisp de nos jours. Cependant, elle ne dispose pas d'une fonction permettant de lister les variables d'environnement. il fonctionne avec les variables d'environnement nous pouvons voir que pour chaque distribution de lisp nous avons une version différente de l'accès aux variables seulement par exemple :
(defun getenv (x)
"Query the environment, as in C getenv.
Beware: may return empty string if a variable is present but empty;
use getenvp to return NIL in such a case."
(declare (ignorable x))
#+(or abcl clasp clisp ecl xcl) (ext:getenv x)
#+allegro (sys:getenv x)
#+clozure (ccl:getenv x)
#+cmucl (unix:unix-getenv x)
#+scl (cdr (assoc x ext:*environment-list* :test #'string=))
#+cormanlisp
(let* ((buffer (ct:malloc 1))
(cname (ct:lisp-string-to-c-string x))
(needed-size (win:getenvironmentvariable cname buffer 0))
(buffer1 (ct:malloc (1+ needed-size))))
(prog1 (if (zerop (win:getenvironmentvariable cname buffer1 needed-size))
nil
(ct:c-string-to-lisp-string buffer1))
(ct:free buffer)
(ct:free buffer1)))
#+gcl (system:getenv x)
#+genera nil
#+lispworks (lispworks:environment-variable x)
#+mcl (ccl:with-cstrs ((name x))
(let ((value (_getenv name)))
(unless (ccl:%null-ptr-p value)
(ccl:%get-cstring value))))
#+mkcl (#.(or (find-symbol* 'getenv :si nil) (find-symbol* 'getenv :mk-ext nil)) x)
#+sbcl (sb-ext:posix-getenv x)
#-(or abcl allegro clasp clisp clozure cmucl cormanlisp ecl gcl genera lispworks mcl mkcl sbcl scl xcl)
(not-implemented-error 'getenv))
(defsetf getenv (x) (val)
"Set an environment variable."
(declare (ignorable x val))
#+allegro `(setf (sys:getenv ,x) ,val)
#+clisp `(system::setenv ,x ,val)
#+clozure `(ccl:setenv ,x ,val)
#+cmucl `(unix:unix-setenv ,x ,val 1)
#+ecl `(ext:setenv ,x ,val)
#+lispworks `(hcl:setenv ,x ,val)
#+mkcl `(mkcl:setenv ,x ,val)
#+sbcl `(progn (require :sb-posix) (symbol-call :sb-posix :setenv ,x ,val 1))
#-(or allegro clisp clozure cmucl ecl lispworks mkcl sbcl)
'(not-implemented-error '(setf getenv))
donc pour obtenir une variable :
CL-USER> (uiop:getenv "GEM_PATH")
"/Users/toni/.rvm/gems/ruby-2.1.6@afs-dev:/Users/toni/.rvm/gems/ruby-2.1.6@global"
comme indiqué dans un commentaire, si vous utilisez SBCL, vous pouvez obtenir ceci avec lui :
SB-EXT:POSIX-ENVIRON
exemple en c :
extern char **environ;
//...
int i = 0;
while(environ[i]) {
printf("%s\n", environ[i++]); // prints in form of "variable=value"
}
| GEM_HOME=/Users/toni/.rvm/gems/ruby-2.1.6@afs-dev |
| SHELL=/bin/bash |
| TERM=dumb |
| TMPDIR=/var/folders/zs/t9wnzpqj2bdgjjgjwb8pqxc80000gn/T/ |
| Apple_PubSub_Socket_Render=/private/tmp/com.apple.launchd.e0K30SfWTc/Render |
| USER=toni |
| SSH_AUTH_SOCK=/private/tmp/com.apple.launchd.KvlUaU8PD5/Listeners |
| __CF_USER_TEXT_ENCODING=0x1F5:0x0:0x8 |
| PATH=/Users/toni/.rvm/gems/ruby-2.1.6@afs-dev/bin:/Users/toni/.rvm/gems/ruby-2.1.6@global/bin:/Users/toni/.rvm/rubies/ruby-2.1.6/bin/:/usr/texbin:/Library/TeX/texbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/toni/.rvm/bin |
| PWD=/Users/toni/learn/lisp/cl-l/stackoverflow/scripts |
| LANG=es_ES.UTF-8 |
| XPC_FLAGS=0x0 |
| XPC_SERVICE_NAME=org.gnu.Emacs.13016 |
| SHLVL=1 |
| HOME=/Users/toni |
| BUNDLE_PATH=/Users/toni/.rvm/gems/ruby-2.1.6@afs-dev |
| LOGNAME=toni |
| GEM_PATH=/Users/toni/.rvm/gems/ruby-2.1.6@afs-dev:/Users/toni/.rvm/gems/ruby-2.1.6@global |
| DISPLAY=/private/tmp/com.apple.launchd.ljkiChb2wE/org.macosforge.xquartz:0 |
| _=/tmp/babel-6131RLH/C-bin-6131T_s |
exemple dans SBCL
(sb-ext:posix-environ)
("TERM=dumb" "TERMCAP=" "COLUMNS=139" "INSIDE_EMACS=25.2.1,comint"
"BUNDLE_PATH=/Users/toni/.rvm/gems/ruby-2.1.6@afs-dev"
"GEM_PATH=/Users/toni/.rvm/gems/ruby-2.1.6@afs-dev:/Users/toni/.rvm/gems/ruby-2.1.6@global"
"GEM_HOME=/Users/toni/.rvm/gems/ruby-2.1.6@afs-dev" "LANG=es_ES.UTF-8"
"XPC_FLAGS=0x0" "USER=toni" "XPC_SERVICE_NAME=org.gnu.Emacs.13016"
"DISPLAY=/private/tmp/com.apple.launchd.ljkiChb2wE/org.macosforge.xquartz:0"
"LOGNAME=toni"
"PATH=/Users/toni/.rvm/gems/ruby-2.1.6@afs-dev/bin:/Users/toni/.rvm/gems/ruby-2.1.6@global/bin:/Users/toni/.rvm/rubies/ruby-2.1.6/bin/:/usr/texbin:/Library/TeX/texbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/toni/.rvm/bin"
"SSH_AUTH_SOCK=/private/tmp/com.apple.launchd.KvlUaU8PD5/Listeners"
"Apple_PubSub_Socket_Render=/private/tmp/com.apple.launchd.e0K30SfWTc/Render"
"SHELL=/bin/bash" "HOME=/Users/toni" "__CF_USER_TEXT_ENCODING=0x1F5:0x0:0x8"
"TMPDIR=/var/folders/zs/t9wnzpqj2bdgjjgjwb8pqxc80000gn/T/"
"SBCL_HOME=/Users/toni/.roswell/impls/x86-64/darwin/sbcl/1.3.16/lib/sbcl"
"ROS_OPTS=((\"program\"\"(:eval\\\"(ros:quicklisp)\\\")\")(\"lispdir\"\"/usr/local/Cellar/roswell/17.4.8.76/etc/roswell/\")(\"verbose\"\"0\")(\"homedir\"\"/Users/toni/.roswell/\")(\"wargv0\"\"/usr/local/bin/ros\")(\"argv0\"\"/usr/local/bin/ros\")(\"quicklisp\"\"/Users/toni/.roswell/lisp/quicklisp/\")(\"impl\"\"sbcl/1.3.16\")(\"dynamic-space-size\"\"3gb\")(\"sbcl.version\"\"1.3.16\")(\"allegro.version\"\"100express\")(\"ccl-bin.version\"\"1.11\")(\"ecl.version\"\"16.1.3\")(\"slime.version\"\"2017.02.27\")(\"sbcl-bin.version\"\"1.2.11\")(\"default.lisp\"\"sbcl\"))")
Donc, pour d'autres implémentations, vous devez chercher comment faire,
Il existe enfin une bonne bibliothèque appelée OSICAT que :
OSICAT est une interface de système d'exploitation légère pour Common Lisp sur plates-formes Unix. Il ne s'agit pas d'une API de type POSIX, mais plutôt d'une simple d'accompagnement des fonctionnalités standard ANSI.
donc dans votre cas vous devez utiliser :
(osicat:environment)
(("TERM" . "dumb") ("TERMCAP" . "") ("COLUMNS" . "139") ("INSIDE_EMACS" . "25.2.1,comint") ("BUNDLE_PATH" . "/Users/toni/.rvm/gems/ruby-2.1.6@afs-dev") ("GEM_PATH" . "/Users/toni/.rvm/gems/ruby-2.1.6@afs-dev:/Users/toni/.rvm/gems/ruby-2.1.6@global") ("GEM_HOME" . "/Users/toni/.rvm/gems/ruby-2.1.6@afs-dev") ("LANG" . "es_ES.UTF-8") ("XPC_FLAGS" . "0x0") ("USER" . "toni") ("XPC_SERVICE_NAME" . "org.gnu.Emacs.13016") ("DISPLAY" . "/private/tmp/com.apple.launchd.ljkiChb2wE/org.macosforge.xquartz:0") ("LOGNAME" . "toni") ("PATH" . "/Users/toni/.rvm/gems/ruby-2.1.6@afs-dev/bin:/Users/toni/.rvm/gems/ruby-2.1.6@global/bin:/Users/toni/.rvm/rubies/ruby-2.1.6/bin/:/usr/texbin:/Library/TeX/texbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/toni/.rvm/bin") ("SSH_AUTH_SOCK" . "/private/tmp/com.apple.launchd.KvlUaU8PD5/Listeners") ("Apple_PubSub_Socket_Render" . "/private/tmp/com.apple.launchd.e0K30SfWTc/Render") ("SHELL" . "/bin/bash") ("HOME" . "/Users/toni") ("__CF_USER_TEXT_ENCODING" . "0x1F5:0x0:0x8") ("TMPDIR" . "/var/folders/zs/t9wnzpqj2bdgjjgjwb8pqxc80000gn/T/") ("ROS_OPTS" . "((\"program\"\"(:eval\\\"(ros:quicklisp)\\\")\")(\"lispdir\"\"/usr/local/Cellar/roswell/17.4.8.76/etc/roswell/\")(\"verbose\"\"0\")(\"homedir\"\"/Users/toni/.roswell/\")(\"wargv0\"\"/usr/local/bin/ros\")(\"argv0\"\"/usr/local/bin/ros\")(\"quicklisp\"\"/Users/toni/.roswell/lisp/quicklisp/\")(\"impl\"\"ccl-bin/1.11\")(\"dynamic-space-size\"\"3gb\")(\"sbcl.version\"\"1.3.16\")(\"allegro.version\"\"100express\")(\"ccl-bin.version\"\"1.11\")(\"ecl.version\"\"16.1.3\")(\"slime.version\"\"2017.02.27\")(\"sbcl-bin.version\"\"1.2.11\")(\"default.lisp\"\"ccl-bin\"))"))
J'espère donc que cela devrait fonctionner