如何在elisp中确定操作系统?

108
我如何在ELisp中编程确定Emacs运行的操作系统?
我希望能够根据操作系统在 .emacs 中运行不同的代码。

1
从GNU Emacs Lisp参考手册 http://www.gnu.org/software/emacs/manual/html_node/elisp/System-Environment.html - WisdomFusion
8个回答

112

system-type变量:

system-type is a variable defined in `C source code'.
Its value is darwin

Documentation:
Value is symbol indicating type of operating system you are using.
Special values:
  `gnu'         compiled for a GNU Hurd system.
  `gnu/linux'   compiled for a GNU/Linux system.
  `darwin'      compiled for Darwin (GNU-Darwin, Mac OS X, ...).
  `ms-dos'      compiled as an MS-DOS application.
  `windows-nt'  compiled as a native W32 application.
  `cygwin'      compiled using the Cygwin library.
Anything else indicates some sort of Unix system.

97

对于不太熟悉elisp的朋友,以下是一个示例用法:

(if (eq system-type 'darwin)
  ; something for OS X if true
  ; optional something if not
)

或者,如果我们不关心else-form并且有多个then-forms

(when (eq system-type 'darwin)
  ; do this
  ; and this ...
)

2
好的,我在Elisp中使用奇怪的分支块(if-和else-part由换行符分隔,块需要progn)时烧伤了自己多次,所以对于不熟悉这些怪癖的每个人的建议是 - 查看此答案 - metakermit
3
如果没有 else 分支,实际上不需要使用 progn 关键字。也就是说,你可以直接使用 when 关键字来代替 if,这样等价于 (if ... (progn ...) '()) - Electric Coffee
1
因为我尝试使用“=”,但它无法正常工作,所以点赞了。 - Philip Daniels
3
你可以这样使用cond(cond ((eq system-type 'gnu/linux) "notify-send") ((eq system-type 'darwin) "growlnotify -a Emacs.app -m"))。其中,当system-typegnu/linux时,返回"notify-send";当system-typedarwin时,返回"growlnotify -a Emacs.app -m" - ealfonso
1
注意:对于单个分支,可以使用“when”。 - Rudolf Adamkovič
显示剩余3条评论

27

我创建了一个简单的宏,可以根据系统类型轻松运行代码:

(defmacro with-system (type &rest body)
  "Evaluate BODY if `system-type' equals TYPE."
  (declare (indent defun))
  `(when (eq system-type ',type)
     ,@body))

(with-system gnu/linux
  (message "Free as in Beer")
  (message "Free as in Freedom!"))

11
在 .emacs 文件中,不仅有 system-type 变量,还有 window-system 变量。 当你想在一些只有 X11 或终端或 MacOS 设置中进行选择时,这是非常有用的。

7

现在Windows系统中也有Linux子系统(Windows 10下的bash),其中system-typegnu/linux。要检测此系统类型,请使用以下命令:

(if
    (string-match "Microsoft"
         (with-temp-buffer (shell-command "uname -r" t)
                           (goto-char (point-max))
                           (delete-char -1)
                           (buffer-string)))
    (message "Running under Linux subsystem for Windows")
    (message "Not running under Linux subsystem for Windows")
  )

2

这个问题大多已经有了答案,但对于那些感兴趣的人,我刚在FreeBSD上测试了一下,报告的值是"berkeley-unix"。


0

最简单的方法是对system-type变量进行模式匹配,像这样:

(pcase system-type
  ;; GNU/Linux or WSL
  (gnu/linux
   (message "This is GNU/Linux"))

  ;; macOS
  (darwin
   (message "This is macOS"))

  ;; Windows
  (windows-nt
   (message "This is Windows")) 

  ;; BSDs
  (berkeley-unix
    (message "This is a BSD"))

  ;; Other operating system
  (_
   (message "Unknown operating system")))

如需更多信息和其他类型的操作系统,请参阅https://www.gnu.org/software/emacs/manual/html_node/elisp/System-Environment.html上有关system-type的完整文档。

(测试上述代码的简单方法是将其粘贴到您的*scratch*缓冲区中,然后在最外层括号后按C-j键)


0

还有(至少在版本24-26中)system-configuration,如果您想要调整构建系统的差异。然而,与system-type变量的文档描述可能包含的值不同,该变量的文档未描述此变量可能包含的可能值。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接