CommonLisp中解析命令行參數(shù)示例
clingon
clingon 是一個 Common Lisp 的命令行選項的解析器,它可以輕松地解析具有復(fù)雜格式的命令行選項。例如,下面的代碼可以打印給定次數(shù)的打招呼信息
#!/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:
稍微做一些解釋。首先執(zhí)行命令ros init hello
生成上面的代碼的雛形——加載依賴、包定義,以及空的函數(shù)main
。為了加載 clingon,將其作為函數(shù)ql:quickload
的參數(shù)。然后分別定義一個command
、handler
,以及option
。
在 clingon 中,類clingon:command
的實例對象表示一個可以在 shell 中被觸發(fā)的命令,它們由函數(shù)clingon:make-command
創(chuàng)建。每一個命令起碼要有三個要素:
:handler
,負(fù)責(zé)使用命令行選項、實現(xiàn)業(yè)務(wù)邏輯的函數(shù);:name
,命令的名字,一般會被展示在命令的用法說明中;:options
,該命令所接受的選項。
此處的:handler
就是函數(shù)top-level/handler
,它會被函數(shù)clingon:run
調(diào)用(依賴注入的味道),并將一個合適的clingon:command
對象傳入。:options
目前只承載了一個選項的定義,即
(clingon:make-option :integer :description "number of greetings" :initial-value 1 :key :count :long-name "count")
它定義了一個值為整數(shù)的選項,在命令行中通過--count
指定。如果沒有傳入該選項,那么在使用函數(shù)clingon:getopt
取值時,會獲得默認(rèn)值 1。如果要從一個命令對象中取出這個選項的值,需要以它的:key
參數(shù)的值作為參數(shù)來調(diào)用函數(shù)clingon:getopt
,正如上面的函數(shù)top-level/handler
所示。
子命令
clingon 也可以實現(xiàn)諸如git add
、git branch
這樣的子命令特性。像add
、branch
這樣的子命令,對于 clingon 而言仍然是類clingon:command
的實例對象,只不過它們不會傳遞給函數(shù)clingon:run
調(diào)度,而是傳遞給函數(shù)clingon:make-command
的參數(shù):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)))
選項與參數(shù)
在 clingon 中通過命令行傳遞給進(jìn)程的信息分為選項和參數(shù)兩種形態(tài),選項是通過名字來引用,而參數(shù)則通過它們的下標(biāo)來引用。
例如在第一個例子中,就定義了一個名為--count
的選項,它在解析結(jié)果中被賦予了:count
這個關(guān)鍵字,可以通過函數(shù)clingon:getopt
來引用它的值;
與之相反,變量name
是從命令行中解析了選項后、剩余的參數(shù)中的第一個,它是以位置來標(biāo)識的。clingon 通過函數(shù)clingon:make-option
來定義選項,它提供了豐富的控制能力。
選項名稱
選項有好幾種名字,一種叫做:key
,是在程序內(nèi)部使用的名字,用作函數(shù)clingon:getopt
的參數(shù)之一;
一種叫做:long-name
,一般為多于一個字符的字符串,如"count"
,在命令行該名稱需要帶上兩個連字符的前綴來使用,如--count 3
;
最后一種叫做:short-name
,為一個單獨的字符,如#\v
,在命令行中帶上一個連字符前綴來使用,如-v
。
必要性與默認(rèn)值
通過傳入?yún)?shù):required t
給函數(shù)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 "打印的英文句號的數(shù)量" :key :n :long-name "n" :required t))))) (clingon:run app argv)))
如果不希望在一些最簡單的情況下也要繁瑣地編寫--n 1
這樣的命令行參數(shù),可以用:initial-value 1
來指定。除此之外,也可以讓選項默認(rèn)讀取指定的環(huán)境變量中的值,使用:env-vars
指定環(huán)境變量名即可
(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 中可以通過往函數(shù)clingon:make-option
傳入:list
來實現(xiàn)。當(dāng)用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
,使用的次數(shù)越多(最多為 3 次),則ssh
打印的調(diào)試信息也就越詳細(xì)。這種類型的選項在 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)))
信號選項
有一些選項只需要區(qū)分【有】和【沒有】兩種情況就可以了,而不需要在意這個選項的值——或者這類選項本身就不允許有值,例如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中解析命令行參數(shù)示例的詳細(xì)內(nèi)容,更多關(guān)于CommonLisp命令行參數(shù)的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
最新Adobe?2022全新上線?Adobe?2022永久免費使用教程
目前adobe2022的配置要求CPU至少是四核,運行內(nèi)存至少是16GB,只支持windows10系統(tǒng),版本號是1809以及更高的版本,下面跟隨小編看下最新Adobe?2022全新上線?Adobe?2022永久免費使用教程,感興趣的朋友一起看看吧2021-12-12Security安裝 Elastic SIEM 和 EDR的超詳細(xì)教程
這篇文章主要介紹了Security安裝 Elastic SIEM 和 EDR的超詳細(xì)教程,本文通過圖文實例相結(jié)合給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-03-03聯(lián)邦學(xué)習(xí)FedAvg中模型聚合過程的理解分析
這篇文章主要為大家介紹了FedAvg中模型聚合過程的理解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05