Cấu hình người dùng của Shell Script. Thực hành tốt nhất?


13

Tôi đang viết một kịch bản shell với một vài biến nên được cấu hình bởi người dùng. Sẽ có một trình cài đặt để tải xuống và định cấu hình tập lệnh, có thể bằng cách đặt một loạt câu hỏi. Kịch bản trong câu hỏi là nhằm vào các nhà phát triển khác.

Điều này có thể được thực hiện theo một số cách:

  1. Sử dụng trình giữ chỗ trong chính tập lệnh và sử dụng sedđể thay thế chúng trong khi cài đặt (đại loại như thế này: /programming/415677/how-to-replace-placeholder-in-a-text-file )

    • Ưu điểm: Tất cả các định nghĩa biến được chứa trong tập lệnh. Thật dễ dàng để tải xuống tập lệnh theo cách thủ công và định cấu hình các biến cho người dùng thích trình chỉnh sửa hơn trình cài đặt.

    • Nhược điểm: Thật khó để cấu hình lại các biến thông qua trình cài đặt một khi chúng được đặt đúng chỗ. Trừ khi tôi tạo một biểu thức chính quy phức tạp hơn sẽ dễ bị lỗi.

  2. Sử dụng một tệp cấu hình , về cơ bản là một tập lệnh shell khác với các bài tập và sử dụng sourceđể bao gồm nó. (Và có lẽ đặt nó vào ~/.scriptname? Kịch bản chính được sao chép vào /usr/local/bin)

    • Ưu điểm: Thật dễ dàng để cấu hình lại tập lệnh. Thậm chí có thể thêm một tham số để thực hiện điều đó từ tập lệnh chính (Có thể cũng sẽ hoạt động trong giải pháp đầu tiên, nhưng việc chỉnh sửa tập lệnh từ chính nó có vẻ không phải là một ý tưởng hay)

    • Nhược điểm: Tập lệnh hiện phụ thuộc vào hai tệp và người dùng được yêu cầu chạy trình cài đặt cho tệp cấu hình được tạo. Điều này có thể được giải quyết bằng cách tự động tạo tập tin cấu hình nếu không tồn tại. Nhưng việc định vị tệp cấu hình bên ngoài vẫn sẽ cồng kềnh hơn đối với người dùng chỉ muốn tải xuống tập lệnh, chỉnh sửa tệp và được thực hiện với nó.

Ngoài ra, một vài tùy chọn liên quan đến cách quản lý cấu hình của người dùng sau khi cài đặt:

  1. Git như
    $ myscript config server.host example.org $ myscript config server.proxypath / home / johndoe / proxy $ myscript config server.httppath / home / johndoe / web

  2. Tương tác
    $ myscript config
    Nhập tên máy chủ của máy chủ: example.org
    Nhập đường dẫn đến proxy trên máy chủ: / home / johndoe / proxy
    Nhập đường dẫn đến thư mục http trên máy chủ: / home / johndoe / web

  3. getopts với các tùy chọn dài
    $ myscript --host example.org --proxypath / home / johndoe / proxy --httppath / home / johndoe / web

  4. Đơn giản
    $ myscript config example.org / home / johndoe / proxy / home / johndoe / web

Có cách nào khác để làm điều này mà bạn sẽ xem xét?
Bất kỳ thực hành tốt nhất, bất cứ điều gì thanh lịch?


2
Tôi không nghi ngờ rằng bạn có thể viết một kịch bản shell thực hiện tất cả điều này, nhưng câu hỏi là tại sao bạn muốn viết một cái gì đó quá phức tạp vì nó yêu cầu một trình cài đặt trong một kịch bản shell. Dù sao, hãy nhìn vào cách hệ thống cấu hình nhân Linux quản lý tệp cấu hình của nó.

Tốt. Tập lệnh 'trình cài đặt' sẽ chỉ tải xuống tập lệnh thực, sao chép tập lệnh vào đúng vị trí của nó và đặt một loạt câu hỏi cho cấu hình (3-4 biến). Bằng cách này, tôi có thể cung cấp cho người dùng một dòng lệnh duy nhất, cài đặt tập lệnh cài đặt và chuyển nó thành / bin / sh. Tôi có thể bỏ qua trình cài đặt và chỉ cần thêm tham số 'install' vào tập lệnh chính. Có lẽ một giải pháp tốt hơn, bạn nghĩ gì?
Charlie Rudenstål

"nhưng câu hỏi là tại sao bạn muốn ghi một cái gì đó rất phức tạp", đây là kịch bản trong câu hỏi: github.com/charlie-rudenstal/depo Tôi đang cố gắng để giảm số lượng các bước người dùng mới được yêu cầu để thực hiện, đặc biệt là trong cài đặt. Nhìn vào làm cho thiết lập máy chủ yêu cầu tự động là tốt.
Charlie Rudenstål

Câu trả lời:


6

Tôi mong đợi gì từ một chương trình lành mạnh (kịch bản shell hay không):

  • Tôi không bao giờ phải thay đổi thực thi để chỉ cấu hình nó. Đây không phải là nhân hệ điều hành.
  • Tôi có thể vượt qua bất kỳ cài đặt bằng cách sử dụng dòng lệnh. Đây là điều bắt buộc đối với mọi mẩu thông tin không có mặc định hợp lý. Ngoại lệ duy nhất là một mật khẩu cần đầu vào tương tác.
  • Tùy chọn, tôi có thể vượt qua một cài đặt bằng biến môi trường.
  • Tôi có thể viết các thiết lập vào một tệp cấu hình và tệp này sẽ được sử dụng nếu nó hiện diện dưới một tên nổi tiếng hoặc được chỉ định rõ ràng bằng cách sử dụng hai phương pháp trên.
  • Tệp cấu hình sử dụng các tên cài đặt và cú pháp rất giống như dòng lệnh.

Lời khuyên tuyệt vời. Đây sẽ là thứ tự ưa thích của bạn? (1) Kiểm tra các cài đặt đã truyền trong dòng lệnh (2) Kiểm tra cài đặt trong .scriptnameConfig trong cùng thư mục (3) Kiểm tra cài đặt trong biến môi trường (4) Kiểm tra cài đặt trong .scriptnameConfig trong ~ / .scriptnameConfig (5) Sử dụng mặc định thiết lập
Charlie Rudenstål

"Tệp cấu hình sử dụng các tên cài đặt và cú pháp rất giống như dòng lệnh." - Cái này trông thế nào? Tôi sẽ sử dụng cú pháp gán cho các kịch bản shell thông thường: SETTING = VALUE. Sẽ không lệnh như cú pháp cảm thấy một chút lạ trong một tập tin cấu hình?
Charlie Rudenstål

Xem cách mounthoặc sshcho phép bạn sử dụng cùng một cú pháp trên dòng lệnh và trong cấu hình. Bạn không cần phải sao chép hoàn toàn cú pháp dòng lệnh; thay vì '--foo = bar', bạn có thể sử dụng 'foo = bar'. Thay vào đó, nếu bạn đã sử dụng 'BarOption: Foo', điều đó sẽ không thuận tiện hơn nhiều: cần phải nhớ nếu trường hợp đó là quan trọng, từ khóa nào được chấp nhận trong tệp và trên dòng lệnh và không thể sao chép-dán lệnh làm việc dòng vào một tập tin cấu hình chỉ với chỉnh sửa mỹ phẩm.
9000

3

Khi tôi cần viết một tập lệnh phức tạp với nhiều tùy chọn cấu hình khác nhau, tôi sử dụng Python với các thư viện argparseConfigParser . Những trợ giúp thực hiện nhưng quy trình áp dụng cho bất kỳ tập lệnh shell nào:

  1. Hãy tìm một tập tin cấu hình. Nếu có, hãy đọc bất kỳ cài đặt nào có trong bảng từ điển / tra cứu.
  2. Phân tích tên đối số dòng lệnh. Đối với mỗi đối số được cung cấp, ghi đè giá trị được tải từ tệp cấu hình nếu nó tồn tại. Đối với bất kỳ đối số nào không được truyền trong dòng lệnh và không có trong cấu hình, hãy sử dụng mặc định.
  3. Thực thi chức năng chính của tập lệnh
  4. Nếu tệp cấu hình không tồn tại, hãy ghi các giá trị được truyền và / hoặc mặc định vào nó.

Sở thích của tôi là cho một tệp cấu hình để giữ các tùy chọn ưa thích khi tập lệnh sẽ được sử dụng nhiều lần, nhưng hãy để bất kỳ đối số dòng lệnh nào ghi đè. Viết tệp cấu hình bằng các tham số đó trong lần đầu tiên chạy. Các tập tin cấu hình sau đó có thể được chia sẻ và cam kết với một kho lưu trữ mã.

Trong trường hợp gần đây nhất của tôi, tôi cũng đã viết các mặc định cho [DEFAULT]phần ở đầu tệp cấu hình, sau đó có một phần cho mỗi "môi trường" với các phần ghi đè thích hợp cho mỗi phần. "Môi trường" là tham số không tên đầu tiên của tập lệnh. Vì vậy, trong trường hợp này, các tham số được chọn là mặc định tích hợp -> mặc định tệp cấu hình -> giá trị phần cấu hình tệp -> tham số dòng lệnh . Một tham số dòng lệnh bổ sung cung cấp tùy chọn ghi đè lên cấu hình hiện có với giá trị của lần chạy mới nhất. Tệp cấu hình này được ghi vào thư mục hiện tại để nó áp dụng cho mỗi dự án và có thể được cam kết với phần còn lại của mã. Bất cứ ai khác kiểm tra cùng một dự án sau đó sẽ bắt đầu với cùng một cấu hình.


"Một tham số dòng lệnh bổ sung cung cấp tùy chọn ghi đè lên cấu hình hiện có với giá trị của lần chạy mới nhất." Đây là một cách tiếp cận thú vị. Một cách thuận tiện để kết hợp các tham số với cấu hình.
Charlie Rudenstål

+1, tôi cũng khuyên bạn nên đặt mặc định trong một default.configtệp nằm trong cùng thư mục với tập lệnh, sau đó tìm tệp cấu hình ~/.scriptnameđể ghi đè các giá trị này. Bằng cách đó, mọi giá trị đều có giá trị mặc định hợp lệ và dễ bảo trì hơn.
Aaron

2

Chỉnh sửa giữ chỗ là dễ bị lỗi.

Tôi sẽ đi với việc sử dụng một tập tin cấu hình.

Mối quan tâm của bạn về sự phụ thuộc là hợp lệ, tuy nhiên, tôi không nhớ sử dụng quá nhiều công cụ bao gồm một tệp duy nhất. Vì vậy, về mặt lý thuyết bạn đúng, nhưng thực tế nó sẽ khá OK.

Một lựa chọn thứ ba là làm cho phần mềm cấu hình viết một phiên bản phù mới là cụ thể cho các tùy chọn và các thông số được chọn. Điều này có thể khó hơn để viết và kiểm tra tất nhiên :)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.