<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
clingon 是一個 Common Lisp 的命令列選項的解析器,它可以輕鬆地解析具有複雜格式的命令列選項。例如,下面的程式碼可以列印給定次數的打招呼資訊
#!/bin/sh #|-*- mode:lisp -*-|# #| exec ros -Q -- $0 "$@" |# (progn ;;init forms (ros:ensure-asdf) #+quicklisp(ql:quickload '(clingon) :silent t) ) (defpackage :ros.script.hello.3868869124 (:use :cl :clingon)) (in-package :ros.script.hello.3868869124) (defun top-level/handler (cmd) (check-type cmd clingon:command) (let ((count (clingon:getopt cmd :count)) (name (first (clingon:command-arguments cmd)))) (dotimes (_ count) (declare (ignorable _)) (format t "Hello ~A!~%" name)))) (defun main (&rest argv) (let ((app (clingon:make-command :handler #'top-level/handler :name "hello" :options (list (clingon:make-option :integer :description "number of greetings" :initial-value 1 :key :count :long-name "count"))))) (clingon:run app argv))) ;;; vim: set ft=lisp lisp:
稍微做一些解釋。首先執行命令ros init hello
生成上面的程式碼的雛形——載入依賴、包定義,以及空的函數main
。為了載入 clingon,將其作為函數ql:quickload
的引數。然後分別定義一個command
、handler
,以及option
。
在 clingon 中,類clingon:command
的範例物件表示一個可以在 shell 中被觸發的命令,它們由函數clingon:make-command
建立。每一個命令起碼要有三個要素:
:handler
,負責使用命令列選項、實現業務邏輯的函數;:name
,命令的名字,一般會被展示在命令的用法說明中;:options
,該命令所接受的選項。此處的:handler
就是函數top-level/handler
,它會被函數clingon:run
呼叫(依賴注入的味道),並將一個合適的clingon:command
物件傳入。:options
目前只承載了一個選項的定義,即
(clingon:make-option :integer :description "number of greetings" :initial-value 1 :key :count :long-name "count")
它定義了一個值為整數的選項,在命令列中通過--count
指定。如果沒有傳入該選項,那麼在使用函數clingon:getopt
取值時,會獲得預設值 1。如果要從一個命令物件中取出這個選項的值,需要以它的:key
引數的值作為引數來呼叫函數clingon:getopt
,正如上面的函數top-level/handler
所示。
clingon 也可以實現諸如git add
、git branch
這樣的子命令特性。像add
、branch
這樣的子命令,對於 clingon 而言仍然是類clingon:command
的範例物件,只不過它們不會傳遞給函數clingon:run
排程,而是傳遞給函數clingon:make-command
的引數:sub-command
,如下列程式碼所示
(defun top-level/handler (cmd) (declare (ignorable cmd))) (defun main (&rest argv) (let ((app (clingon:make-command :handler #'top-level/handler :name "cli" :sub-commands (list (clingon:make-command :handler #'(lambda (cmd) (declare (ignorable cmd)) (format t "Dropped the database~%")) :name "dropdb") (clingon:make-command :handler #'(lambda (cmd) (declare (ignorable cmd)) (format t "Initialized the database~%")) :name "initdb"))))) (clingon:run app argv)))
在 clingon 中通過命令列傳遞給程序的資訊分為選項和引數兩種形態,選項是通過名字來參照,而引數則通過它們的下標來參照。
例如在第一個例子中,就定義了一個名為--count
的選項,它在解析結果中被賦予了:count
這個關鍵字,可以通過函數clingon:getopt
來參照它的值;
與之相反,變數name
是從命令列中解析了選項後、剩餘的引數中的第一個,它是以位置來標識的。clingon 通過函數clingon:make-option
來定義選項,它提供了豐富的控制能力。
選項有好幾種名字,一種叫做:key
,是在程式內部使用的名字,用作函數clingon:getopt
的引數之一;
一種叫做:long-name
,一般為多於一個字元的字串,如"count"
,在命令列該名稱需要帶上兩個連字元的字首來使用,如--count 3
;
最後一種叫做:short-name
,為一個單獨的字元,如#v
,在命令列中帶上一個連字元字首來使用,如-v
。
通過傳入引數:required t
給函數clingon:make-option
,可以要求一個選項為必傳的。
例如下面的命令的選項--n
就是必傳的
(defun top-level/handler (cmd) (dotimes (i (clingon:getopt cmd :n)) (declare (ignorable i)) (format t "."))) (defun main (&rest argv) (let ((app (clingon:make-command :handler #'top-level/handler :name "dots" :options (list (clingon:make-option :integer :description "列印的英文句號的數量" :key :n :long-name "n" :required t))))) (clingon:run app argv)))
如果不希望在一些最簡單的情況下也要繁瑣地編寫--n 1
這樣的命令列引數,可以用:initial-value 1
來指定。除此之外,也可以讓選項預設讀取指定的環境變數中的值,使用:env-vars
指定環境變數名即可
(defun top-level/handler (cmd) (format t "Hello ~A~%" (clingon:getopt cmd :username))) (defun main (&rest argv) (let ((app (clingon:make-command :handler #'top-level/handler :name "greet" :options (list (clingon:make-option :string :description "使用者名稱" :env-vars '("GREETER_USERNAME") :key :username :long-name "username"))))) (clingon:run app argv)))
像curl
中的選項-H
就是可以多次使用的,每指定一次就可以在請求中新增一個 HTTP 頭部,如下圖所示
在 clingon 中可以通過往函數clingon:make-option
傳入:list
來實現。當用clingon:getopt
取出型別為:list
的選項的值時,得到的是一個列表,其中依次存放著輸入的值的字串。
(defun top-level/handler (cmd) (let ((messages (clingon:getopt cmd :message))) (format t "~{~A~^~%~}" messages))) (defun main (&rest argv) (let ((app (clingon:make-command :handler #'top-level/handler :name "commit" :options (list (clingon:make-option :list :description "提交的訊息" :key :message :long-name "message" :short-name #m))))) (clingon:run app argv)))
另一種情況是儘管沒有值,但仍然多次使用同一個選項。例如命令ssh
的選項-v
,使用的次數越多(最多為 3 次),則ssh
列印的偵錯資訊也就越詳細。這種型別的選項在 clingon 中稱為:counter
。
(defun top-level/handler (cmd) (format t "Verbosity: ~D~%" (clingon:getopt cmd :verbose))) (defun main (&rest argv) (let ((app (clingon:make-command :handler #'top-level/handler :name "log" :options (list (clingon:make-option :counter :description "囉嗦程度" :key :verbose :long-name "verbose" :short-name #v))))) (clingon:run app argv)))
有一些選項只需要區分【有】和【沒有】兩種情況就可以了,而不需要在意這個選項的值——或者這類選項本身就不允許有值,例如docker run
命令的選項-d
和--detach
。
這種選項的型別為:boolean/true
,如果指定了這個選項,那麼取出來的值始終為t
。與之相反,型別:boolean/false
取出來的值始終為nil
。
(defun top-level/handler (cmd) (let ((rv (software-type))) (when (clingon:getopt cmd :shout) (setf rv (concatenate 'string (string-upcase rv) "!!!!111"))) (format t "~A~%" rv))) (defun main (&rest argv) (let ((app (clingon:make-command :handler #'top-level/handler :name "info" :options (list (clingon:make-option :boolean/true :description "大喊" :key :shout :long-name "shout"))))) (clingon:run app argv)))
如果一個選項儘管接受的是字串,但並非所有輸入都是有意義的,例如命令dot
的選項-T
。從dot
的 man 檔案可以看到,它所支援的圖片型別是有限的,如ps
、pdf
、png
等。
比起宣告一個:string
型別的選項,讓 clingon 代勞輸入值的有效性檢查來得更輕鬆,這裡可以使用:choice
型別
(defun top-level/handler (cmd) (format t "~A~%" (clingon:getopt cmd :hash-type))) (defun main (&rest argv) (let ((app (clingon:make-command :handler #'top-level/handler :name "digest" :options (list (clingon:make-option :choice :description "雜湊型別" :items '("MD5" "SHA1") :key :hash-type :long-name "hash-type"))))) (clingon:run app argv)))
以上就是CommonLisp中解析命令列引數範例的詳細內容,更多關於CommonLisp命令列引數的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45