2017-05-29 178 views
2

我想列舉在我的Lisp進程中可用的所有環境變量的列表。我想要C變量environ返回的相同列表。如何獲取Lisp進程中可用的所有環境變量的列表?

SBCL和Clozure CL都沒有提供開箱即用的功能。我可以使用CFFI嗎?

+2

SBCL有'SB-EXT:POSIX-ENVIRON'。 – jkiiski

+0

很好..謝謝! CCL有類似的東西嗎? –

+0

對於CCL,請參閱[操作系統接口](https://ccl.clozure.com/docs/ccl.html#operating-system-interface)。 – Renzo

回答

6

與操作系統和通用lisp的接口仍然完全依賴於您的lisp分發。所以或多或少都不容易找到一個適用於所有CL發行版的好庫。

我建議你使用帶有ASDF 3及以上版本的UIOP,它是目前在常見lisp中使用操作系統的最佳庫。然而,它沒有一個功能列出的環境變量,furthermother如果我們看一看如何it works with environment varables我們可以看到,對於每一個口齒不清的分佈,我們有不同的版本,訪問這些變量只例如:

(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)) 

所以爲獲得一個變量:

CL-USER> (uiop:getenv "GEM_PATH") 
"/Users/toni/.rvm/gems/[email protected]:/Users/toni/.rvm/gems/[email protected]" 

爲指向一個評論,如果你是usign SBCL你可以用它得到這樣的:

SB-EXT:POSIX-ENVIRON

例如C:在SBCL

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/[email protected]                                              | 
| 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/[email protected]/bin:/Users/toni/.rvm/gems/[email protected]/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/[email protected]                                             | 
| LOGNAME=toni                                                       | 
| GEM_PATH=/Users/toni/.rvm/gems/[email protected]:/Users/toni/.rvm/gems/[email protected]                                    | 
| DISPLAY=/private/tmp/com.apple.launchd.ljkiChb2wE/org.macosforge.xquartz:0                                        | 
| _=/tmp/babel-6131RLH/C-bin-6131T_s                                                  | 

例如

(sb-ext:posix-environ) 


("TERM=dumb" "TERMCAP=" "COLUMNS=139" "INSIDE_EMACS=25.2.1,comint" 
"BUNDLE_PATH=/Users/toni/.rvm/gems/[email protected]" 
"GEM_PATH=/Users/toni/.rvm/gems/[email protected]:/Users/toni/.rvm/gems/[email protected]" 
"GEM_HOME=/Users/toni/.rvm/gems/[email protected]" "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/[email protected]/bin:/Users/toni/.rvm/gems/[email protected]/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\"))") 

所以你MUT研究如何其他實現,

最後有一個好的圖書館稱爲OSICAT說:

OSICAT是一個輕量級操作系統inter面向Common Lisp的 Unix平臺。它不是一個POSIX風格的API,而是一個簡單的標準ANSI設施伴奏。

所以你的情況,你必須使用:

(osicat:environment) 

(("TERM" . "dumb") ("TERMCAP" . "") ("COLUMNS" . "139") ("INSIDE_EMACS" . "25.2.1,comint") ("BUNDLE_PATH" . "/Users/toni/.rvm/gems/[email protected]") ("GEM_PATH" . "/Users/toni/.rvm/gems/[email protected]:/Users/toni/.rvm/gems/[email protected]") ("GEM_HOME" . "/Users/toni/.rvm/gems/[email protected]") ("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/[email protected]/bin:/Users/toni/.rvm/gems/[email protected]/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\"))")) 

所以我希望這應該工作

+0

添加一些文檔:[lisp-cookbook(github更新版本)](https://lispcookbook.github.io/cl-cookbook/os.html)。 – Ehvince

+0

是的,它確實有效。謝謝! –

相關問題