2012-03-05 28 views
10

Tôi đã thử nghiệm optcomplete làm việc với mô-đun optparse. Ví dụ của nó là một tệp đơn giản để tôi có thể làm việc đó. Tôi cũng đã thử nghiệm nó bằng cách sử dụng mô-đun argparse vì mô-đun trước không được dùng nữa. Nhưng tôi thực sự không hiểu làm thế nào và bởi ai mà chương trình python được gọi trên máy ép tab. Tôi nghi ngờ bash cùng với đường dây shebang và mô-đun argparse (hoặc optparse) có liên quan theo một cách nào đó. Tôi đã cố gắng để tìm ra điều này (bây giờ sẽ đọc mã nguồn).Làm thế nào để argparse (và phản đối không được chấp nhận) trả lời 'tab' nhấn phím sau tên chương trình python, trong bash?

Tôi có cấu trúc chương trình phức tạp hơn một chút, bao gồm một trình bao bọc xung quanh đoạn mã xử lý đối số. argparse.ArgumentParser() instantiation của nó và các cuộc gọi đến add_argument() - được superclassed vào một mô-đun trung gian để tránh trùng lặp mã, và wrapper xung quanh đó đang được gọi là - là bên trong một chức năng.

Tôi muốn hiểu cách hoàn thành tab này hoạt động giữa bash và python (hoặc cho vấn đề đó bất kỳ người giải thích nào khác như perl).

LƯU Ý: Tôi có một sự hiểu biết công bằng về hoàn thành bash (mà tôi vừa học được), và tôi nghĩ rằng tôi hiểu hoàn thành tùy chỉnh bash (chỉ).

LƯU Ý: Tôi đã đọc tương tự khác SO câu hỏi, và không ai thực sự trả lời Q. này

Edit: Here là chức năng bash.
tôi đã hiểu cách các mô-đun python được biết về những lời gõ vào dòng lệnh, bằng cách đọc os.environ giá trị của biến

$COMP_WORDS 
$COMP_CWORD 
$COMP_LINE 
$COMP_POINT 
$COMPREPLY 

Các biến này có giá trị duy nhất trên tab báo chí. Câu hỏi của tôi là mô-đun python được kích hoạt như thế nào?

+0

Tài liệu 'optcomplet' nói:" Bạn cũng cần mã nguồn hàm Bash và sau đó yêu cầu Bash kích hoạt hoàn thành không hoàn thành cho các chương trình cụ thể sử dụng nó: ". Nếu bạn đã làm điều đó, tại sao bạn vẫn hỏi làm thế nào nó hoạt động? Nó sẽ được rõ ràng bạn chỉ cần nói với bash những gì chương trình để gọi nếu hoàn thành được yêu cầu. –

+0

Xin lỗi, tôi hiểu lầm những gì tôi đọc. Tôi sẽ thêm một câu trả lời cho điều đó. –

Trả lời

14

Để hiểu những gì đang xảy ra ở đây, chúng ta hãy kiểm tra những gì mà chức năng bash thực sự thực hiện:

COMPREPLY=($(\ 
    COMP_LINE=$COMP_LINE COMP_POINT=$COMP_POINT \ 
    COMP_WORDS="${COMP_WORDS[*]}" COMP_CWORD=$COMP_CWORD \ 
    OPTPARSE_AUTO_COMPLETE=1 $1)) 

Xem $1 ở cuối? Điều đó có nghĩa rằng nó thực sự gọi các tập tin Python chúng tôi muốn thực hiện với các biến môi trường đặc biệt được thiết lập! Để theo dõi những gì đang xảy ra, chúng ta hãy chuẩn bị một kịch bản ít để đánh chặn những gì optcomplete.autocomplete làm:

#!/usr/bin/env python2 
import os, sys 
import optparse, optcomplete 
from cStringIO import StringIO 

if __name__ == '__main__':  
    parser = optparse.OptionParser() 

    parser.add_option('-s', '--simple', action='store_true', 
         help="Simple really simple option without argument.") 

    parser.add_option('-o', '--output', action='store', 
         help="Option that requires an argument.") 

    opt = parser.add_option('-p', '--script', action='store', 
          help="Option that takes python scripts args only.") 
    opt.completer = optcomplete.RegexCompleter('.*\.py') 

    # debug env variables 
    sys.stderr.write("\ncalled with args: %s\n" % repr(sys.argv)) 
    for k, v in sorted(os.environ.iteritems()): 
     sys.stderr.write(" %s: %s\n" % (k, v)) 

    # setup capturing the actions of `optcomplete.autocomplete` 
    def fake_exit(i): 
     sys.stderr.write("autocomplete tried to exit with status %d\n" % i) 
    sys.stdout = StringIO() 
    sys.exit = fake_exit 

    # Support completion for the command-line of this script. 
    optcomplete.autocomplete(parser, ['.*\.tar.*']) 

    sys.stderr.write("autocomplete tried to write to STDOUT:\n") 
    sys.stderr.write(sys.stdout.getvalue()) 
    sys.stderr.write("\n") 

    opts, args = parser.parse_args() 

này cho chúng ta sau khi chúng tôi cố gắng tự động hoàn thành nó:

$ ./test.py [tab] 
called with args: ['./test.py'] 
    ... 
    COMP_CWORD: 1 
    COMP_LINE: ./test.py 
    COMP_POINT: 10 
    COMP_WORDS: ./test.py 
    ... 
    OPTPARSE_AUTO_COMPLETE: 1 
    ... 
autocomplete tried to exit with status 1 
autocomplete tried to write to STDOUT: 
-o -h -s -p --script --simple --help --output 

Vì vậy optcomplete.autocomplete chỉ đọc môi trường, chuẩn bị các trận đấu, ghi chúng vào STDOUT và thoát. Kết quả -o -h -s -p --script --simple --help --output sau đó được đưa vào một mảng bash (COMPREPLY=(...)) và trả về bash để trình bày các lựa chọn cho người dùng. Không có phép thuật nào liên quan :)

+0

Hey cảm ơn rất nhiều, trên thực tế, tôi nhận thấy rằng $ 1 khi tôi đọc bình luận của bạn và đi trên trang để có được liên kết.Sau đó, tôi đã bị ấn tượng bởi những gì tôi đã biết nhưng không bao giờ được sử dụng như tôi không bao giờ viết bất kỳ kịch bản bash - $ 1 là đầu tiên arg.-: S. Đó là ngớ ngẩn của tôi mà tôi đã không nhận được rằng trước đó. – 0xc0de

+0

+1 cho một ví dụ đẹp và rõ ràng :) – 0xc0de