2 votes

Comment obtenir la liste de toutes les variables d'environnement disponibles dans un processus Lisp ?

Je veux énumérer la liste de toutes les variables d'environnement disponibles dans mon processus Lisp. Je veux la même liste que celle qui est retournée par la variable C environ .

Ni SBCL ni Clozure CL ne semblent le fournir d'emblée. Puis-je le faire en utilisant CFFI ?

6voto

anquegi Points 5646

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X