2009-07-29 58 views
138

Tôi viết một ứng dụng dòng lệnh nhỏ trong Java. Ứng dụng này sẽ hoạt động với kết hợp các tham số và lệnh, tương tự như svn.Thư viện Java để phân tích cú pháp tham số dòng lệnh?


Ví dụ

app url command1 
app url command2 --parameter2 -x 
app url command1 --param-with-argument argument 
app --parameter url command1 
app --no-url command2 
app --help 


Wanted

  • Tồn tại một thư viện để dễ dàng sử dụng cho Ja va
  • Hỗ trợ phân tích như vậy lệnh dòng
  • (Bonus) Tự động tạo ra một sự giúp đỡ thích hợp
+1

Câu hỏi cũ liên quan chặt chẽ hơn: http://stackoverflow.com/questions/435740/are-there-good-java-libraries-that-facilitate-building-command-line-applications – Jonik

+1

bản sao có thể có của [Có tốt không trình phân tích cú pháp đối số dòng lệnh cho Java?] (http://stackoverflow.com/questions/367706/is-there-a-good-command-line-argument-parser-for-java) –

+1

Đây là một câu hỏi hay mà xứng đáng trên http://softwarerecs.stackexchange.com/. –

Trả lời

82

Tôi là một fan hâm mộ của Commons CLI.

Bạn có thể đặt để hiểu lệnh, cờ (có tên ngắn và dài), có hoặc không có lệnh/công tắc nhất định được yêu cầu hoặc nếu chúng có giá trị mặc định. Nó thậm chí còn có chức năng in ra một tin nhắn loại --help hữu ích.

Trang Usage Scenarios có một số ví dụ hay về cách sử dụng.

+0

Hy. Nó đã được một thời gian dài, nhưng tôi không thể nhận được apache cli bắt lệnh của tôi, chỉ có cờ. Và tôi không thể tìm thấy một ví dụ cho nó. =/ –

54

Hãy thử args4j:http://args4j.kohsuke.org

tôi thích args4j để Commons CLI. (Và tôi đã sử dụng cả hai.)

Với args4j, bạn không cần phải gọi bất kỳ chức năng nào. Mọi thứ đã hoàn tất cho bạn! (Các tham số được đặt thành các trường đối tượng thông qua sự phản chiếu.)

+10

Chúng tôi cũng sử dụng args4j. Một nhược điểm là bạn không thể chỉ định các tùy chọn đa giá trị trong kiểu '-file input1.txt input2.txt'. Bạn phải chỉ định tùy chọn chuyển đổi trước mỗi giá trị một lần nữa ('-file input1.txt -file input2.txt') có thể là một bất lợi nếu bạn muốn sử dụng bash mở rộng (vì vậy' -file input * .txt' là ** không ** có thể) – MRalwasser

+2

Dự án được chuyển đến http://args4j.kohsuke.org/ –

+0

Tùy chọn đa giá trị không còn được hỗ trợ như của args4j 2.0.23 ... – ochedru

28

JewelCLI là Java library for command-line parsing that yields clean code. Nó sử dụng các giao diện Proxied được cấu hình với các chú thích để tự động xây dựng một API an toàn kiểu cho các tham số dòng lệnh của bạn.

Một giao diện ví dụ tham số Person.java:

import uk.co.flamingpenguin.jewel.cli.Option; 

public interface Person { 
    @Option String getName(); 
    @Option int getTimes(); 
} 

Một cách sử dụng ví dụ về giao diện thông số Hello.java:

import static uk.co.flamingpenguin.jewel.cli.CliFactory.parseArguments; 
import uk.co.flamingpenguin.jewel.cli.ArgumentValidationException; 

public class Hello { 
    public static void main(String [] args) { 
     try { 
      Person person = parseArguments(Person.class, args); 
      for (int i = 0; i < person.getTimes(); i++) 
       System.out.println("Hello " + person.getName()); 
     } catch(ArgumentValidationException e) { 
      System.err.println(e.getMessage()); 
     } 
    } 
} 

Lưu bản sao của các tập tin trên vào một thư mục duy nhất và tải về JewelCLI 0.7.6 JAR vào thư mục đó cũng.

Biên dịch và chạy ví dụ trong Bash trên Linux/Mac OS X/v.v.:

javac -cp jewelcli-0.7.6.jar:. Person.java Hello.java 
java -cp jewelcli-0.7.6.jar:. Hello --name="John Doe" --times=3 

Biên dịch và chạy ví dụ trong Windows Command Prompt:

javac -cp jewelcli-0.7.6.jar;. Person.java Hello.java 
java -cp jewelcli-0.7.6.jar;. Hello --name="John Doe" --times=3 

Chạy ví dụ nên năng suất đầu ra sau đây:

Hello John Doe 
Hello John Doe 
Hello John Doe 
+0

Như bạn có thể thấy JewelCLI làm cho việc phân tích cú pháp dòng lệnh đơn giản và an toàn. Nó cũng không có hành lý phụ thuộc để kéo theo đó là một hiếm trong những ngày này. –

+0

Cảm ơn bạn đã chỉnh sửa URL @deterb :) –

+0

Cảm ơn bạn đã sửa liên kết @flamingpenguin :) –

3

JSAP trông khá tốt đối với tôi.

http://sourceforge.net/projects/jsap/

+0

Thông tin: Tệp được phát hành cuối cùng của JSAP đã có trong 2006 – MRalwasser

+0

Có thể cũ, nhưng vẫn hoạt động như một sự quyến rũ đối với tôi. Tuy nhiên, các phụ thuộc phức tạp như "Nếu tham số A được đưa ra, tham số B phải nhỏ hơn A" không thể được diễn tả tự động. – kap

15

Nó cũng đáng xem xét --jopt-simple.

Nó 'cố gắng tôn vinh các cú pháp tùy chọn dòng lệnh của POSIX getopt() và GNU getopt_long().' Dường như có một số lực kéo cộng đồng, đáng chú ý là dòng lệnh phân tích cú pháp lib của sự lựa chọn cho OpenJDK (và Minecraft!).

19

Đối với đầy đủ vì chúng ta hãy thêm JCommander https://github.com/cbeust/jcommander

public class JCommanderTest { 
    @Parameter 
    public List<String> parameters = Lists.newArrayList(); 

    @Parameter(names = { "-log", "-verbose" }, description = "Level of verbosity") 
    public Integer verbose = 1; 

    @Parameter(names = "-groups", description = "Comma-separated list of group names to be run") 
    public String groups; 

    @Parameter(names = "-debug", description = "Debug mode") 
    public boolean debug = false; 
} 

và một ví dụ sử dụng

CommanderTest jct = new JCommanderTest(); 
String[] argv = { "-log", "2", "-groups", "unit", "a", "b", "c" }; 
new JCommander(jct, argv); 

Assert.assertEquals(jct.verbose.intValue(), 2); 
+1

Từ http://jcommander.org/: "JCommander: Vì cuộc sống quá ngắn để phân tích cú pháp tham số dòng lệnh". –

+0

Tôi vừa thử thư viện CLI Commons, thấy cực kỳ bực bội khi sử dụng, chuyển sang JCommander và không hối hận! Một cái gì đó đơn giản như chấp nhận các tùy chọn không rõ là vô cùng phức tạp để đạt được với Commons CLI. Đó là một lớp lót, mặt khác với JCommander. –

3

Tôi đang sử dụng không vận cho một dự án tôi đang làm việc trên, dường như làm việc khá độc đáo:

https://github.com/airlift/airline

Simple Maven depen dency mà bạn cần phải thêm:

<dependency> 
    <groupId>io.airlift</groupId> 
    <artifactId>airline</artifactId> 
    <version>0.6</version> 
</dependency> 

Và sau đó chú thích cũng có cách hiển thị văn bản trợ giúp khá gọn gàng.

có thể xem một ví dụ ở đây nếu nó hữu ích:

https://github.com/mneedham/neo4j-web-importer/blob/master/src/main/java/org/neo4j/dataimport/Neo4jImporter.java

+1

Thật không may, điều này kéo trong một phụ thuộc 1,8 MB (Guava). Kích thước của tiện ích dòng lệnh mà tôi viết chỉ tăng thêm 10 lần, chỉ để hỗ trợ các tùy chọn dòng lệnh ... – cambecc

52

Dưới đây là một tương đối cập nhật (Tính đến tháng 8 năm 2017) danh sách các thư viện mà trả lời câu hỏi của bạn.

Nếu bạn đang tìm kiếm một đề nghị, tôi khuyên bạn nên JOpt đơn giản hoặc JewelCli.

+2

JCommander là một trong những tính năng mới được cập nhật trong danh sách này. –

+3

Tính đến ngày 12 tháng 5 năm 2015, Đơn giản JOpt vẫn được sử dụng trong OpenJDK. Điều đó có vẻ giống như lời chứng thực hữu ích nhất mà tôi có thể nghĩ đến. – Ivar

+2

Vâng, Ivar, tôi đồng ý với bạn rằng JOpt Simple không chỉ đơn giản để sử dụng, mà là hoàn chỉnh. JCommander sẽ phù hợp với những người có một fetish cho các chú thích ràng buộc. –

4

Commandline là dựa trên chú thích, cho phép các quy tắc phức tạp để kết hợp các đối số (chuỗi, lồng nhau, đối số, loại, ...) và được ghi lại hợp lý.

Để sử dụng nó, thêm

<dependency> 
    <groupId>com.github.jankroken</groupId> 
    <artifactId>commandline</artifactId> 
    <version>1.7.0</version> 
</dependency> 

để pom của bạn, và tuyên bố các tùy chọn có sẵn như sau:

public class CommandOptions { 
    private List<String> commands = null; 
    private boolean parameter = false; 
    private boolean url = true; 
    private boolean help = false; 

    @LooseArguments 
    public void setCommands(List<String> commands) { 
    this.commands = commands; 
    } 

    @LongSwitch("parameter") 
    @Toggle(true) 
    public void setParameter(boolean parameter) { 
    this.parameter=parameter; 
    } 

    @LongSwitch("noURL") 
    @Toggle(false) 
    public void setUrl(boolean url) { 
    this.url = url; 
    } 

    @longSwitch("help") 
    @Toggle(true) 
    public void setHelp(boolean help) { 
    this.help = help; 
    } 

    // getters 
} 

và sau đó thực sự phân tích dòng lệnh, làm

public final static void main(String[] args) { 
    try { 
    CommandOptions options = CommandLineParser.parse(CommandOptions.class, args, OptionStyle.SIMPLE); 

    // and then you can pass options to your application logic... 

    } catch 
    ... 
    } 
} 

lưu ý rằng nó chưa (chưa) chứa văn bản trợ giúp được tạo tự động. Đây là nguyên mẫu, nhưng bị hủy bỏ. Việc tạo một văn bản trợ giúp cơ bản cho các trường hợp đơn giản là dễ dàng, nhưng đối với các cấu hình phức tạp hơn (ae các tùy chọn có sẵn cho ứng dụng như "find" hoặc "gcc"), kết quả sẽ không đẹp, và bạn có thể muốn tự kiểm soát bố cục.

Các vấn đề liên quan