我想知道是否有办法从Common Lisp的REPL中获取Linux的PID(进程ID)。也就是说,我想从流程本身的REPL知道SBCL或Allegro流程的ID。
答案 0 :(得分:7)
Common Lisp规范中没有实现此目的的东西。进程ID过于依赖于实现。
在SBCL中,SB-POSIX
软件包为大多数POSIX系统调用提供了Lisp接口,因此您将使用(sb-posix:getpid)
。
在Allegro CL中,操作系统接口功能位于EXCL.OSI
包中,因此您将使用(excl.ose:getpid)
答案 1 :(得分:4)
有一种(基本上)可移植的方法来执行此操作。 CL提供读取文件的功能,并且可以观察到当前进程的pid位于/proc/self/status
中(而且/proc/self
是指向该进程的pid的符号链接,但我认为没有可移植的读取链接)
具体来说,/proc/self/status
是一个文本文件,其中包含如下一行:
Pid: 439
因此您可以解析文件以提取出来。
但是一旦有了pid,没有系统调用或/proc
怪异
答案 2 :(得分:3)
最终解决方案(在很大程度上由@Dan Robertson's和@coredump-谢谢!)
实际上@Dan Robertson给出了完整的答案-我回想起来。 这个答案只是他所说的实现。所以给他点!
(ql:quickload "CL-PPCRE") ;; for regex parsing
(defun get-this-pid ()
"Return PID of this current lisp process."
(with-open-file (in #P"/proc/self/status")
(loop for line = (read-line in nil)
while line
when (ppcre:scan "^Pid" line)
do (return (car
(ppcre:all-matches-as-strings "\\d+"
line))))))
;; to get current process id, call:
(get-this-pid) ;
;; returns for me at the moment using sbcl "12646"
;; this is correct as closing of all other sbcl processes
;; and doing "pidof sbcl" in the shell showed.
正如@Don Robertson所指出的,文件/proc/self/status
显示了打开其“ PID”编号的程序(每个程序对它的看法都不相同)。谢谢唐,因为这解决了在计算机上独立运行多个Lisp程序时,在外壳中真正找到程序PID(pidof sbcl
的PID会给出多个数字的问题。
调用外部程序已过时,如果我们从cl内部打开该文件,就像@coredump指出的那样。
其他程序的PID号
;; Thanks to @coredump - who suggested to use
;; `ppcre:split :whitespace-char-class` for capturing arbitrary numbers
;; in the answer string - I added a test for integer-string-p to clean
;; non-numberic values after split.
(ql:quickload "CL-PPCRE")
(defun integer-string-p (string)
"Does string constist only of '01234567890' characters?"
(reduce (lambda (x y) (and x y))
(mapcar (lambda (c) (member c (coerce "1234567890" 'list)))
(coerce string 'list))))
(defun extract-integers-from-string (s)
"Return integer-words of s."
(let ((l (ppcre:split :whitespace-char-class s)))
(remove-if-not #'integer-string-p l)))
(defun pid-numbers (program-name)
"Return PID numbers of a program in current machine."
(let ((pid-line (with-output-to-string (out)
(external-program:run "pidof" (list program-name)
:output out))))
(extract-integers-from-string pid-line)))
;; call it
(pid-numbers "sbcl")
(pid-numbers "firefox")
;; * (pid-numbers "sbcl")
;; ("16636" "12346")
;; * (pid-numbers "firefox")
;; ("24931" "19388" "19122" "10800" "10745") ; yeah I have many open :D