Trong các tập lệnh cấu hình shell, làm thế nào tôi có thể tính đến sự khác biệt giữa các coreutils trên BSD so với GNU?


9

Cho đến tháng này, các cấu hình shell của tôi khá đơn giản ( chủ yếu là một .bashrchoặc .bash_profilevới một số bí danh), nhưng tôi đã cấu trúc lại nó để tôi có thể có các hành vi khác nhau tùy thuộc vào việc tôi đang sử dụng zsh và bash. Đầu tiên họ cung cấp một tệp cấu hình shell chung nên hoạt động cho bất cứ điều gì, sau đó chuyên biệt cho trình bao cụ thể đang được sử dụng (tôi liên kết với điều này).

Tôi đã ngạc nhiên ngày hôm nay khi lsngừng làm việc. Hóa ra trong quá trình tái cấu trúc .bashrc, có một bí danh

alias ls='ls --color=always'

điều đó đã phá vỡ mọi thứ lstrong bash trên Terminal trong OSX. Khi tôi thấy BSD lsthích -Gmàu sắc, nhưng GNU (hoặc bất cứ thứ gì có trên Ubuntu) thích --color, rõ ràng có khá nhiều tùy chọn khác nhau.

Câu hỏi của tôi là, cách tốt nhất để giải thích cho sự khác biệt trong các tùy chọn và như vậy giữa lõi BSD và GNU là gì? Tôi có nên kiểm tra biến env trong ifcác khối để xem HĐH nào đang được sử dụng và áp dụng hành vi đúng không? Hoặc nó có ý nghĩa hơn để tạo các tệp cấu hình riêng biệt cho mỗi hệ điều hành?

Mặc dù câu trả lời cho những câu hỏi này có thể mang tính chủ quan, nhưng có vẻ như một loạt các phạm vi khác nhau giữa các lõi và chiến lược của BSD và GNU để giải quyết các cấu hình chung có thể sử dụng được trên hầu hết * nix sẽ khá khách quan.


Thay đổi vỏ sẽ không sửa chữa bất cứ điều gì, và ls -ckhác với ls --color. Chỉnh sửa câu hỏi của bạn để sửa chữa.
Mikel

Câu trả lời:


9

Cách đáng tin cậy duy nhất để viết các tập lệnh hỗ trợ các hệ điều hành khác nhau là chỉ sử dụng các tính năng được xác định bởi POSIX.

Đối với những thứ như cấu hình vỏ cá nhân của bạn, bạn có thể sử dụng các bản hack phù hợp với trường hợp sử dụng cụ thể của bạn. Một cái gì đó như sau là xấu xí, nhưng sẽ hoàn thành mục tiêu.

if ls --version 2>/dev/null | grep -q 'coreutils'; then
    alias ls='ls --color=always'
else
    alias ls='ls -G'
fi

Tôi đã chơi xung quanh với các phương pháp khác nhau và tôi nghĩ giải pháp "xấu xí" của bạn là khá tốt và thậm chí không xấu. Hóa ra, tôi đã không nhận thấy sự không phù hợp trong các tùy chọn cho ls trước đó vì tôi đang sử dụng lõi GNU từ Cổng. Đây là một ví dụ tại sao thực hiện 'nếu' trên $ OSTYPE có thể không cung cấp kết quả mong muốn.
mê cung

Có cách nào để khắc phục lỗi xuất phát từ "if ls --version" khi GNU coreutils không có mặt (nhưng vẫn có thể kiểm tra coreutils) không?
mê cung

Oh, đừng bận tâm về việc ngăn chặn lỗi. Tôi chỉ chuyển hướng stderr đến / dev / null trước khi chuyển sang grep và nó hoạt động như tôi muốn.
mê cung

3
Thay vì tìm kiếm coreutilsmột cách rõ ràng, tại sao không kiểm tra xem cờ màu có hoạt động không, vd if ls --color=auto -d / >/dev/null 2>&1; then ....
Mikel

@mikel nếu bạn chỉ quan tâm đến màu sắc (như trong ví dụ), điều đó là tốt. Nếu bạn quan tâm đến các tính năng khác, việc kiểm tra coreutils là hữu ích.
jordanm

3

Xả mã với các ifcâu lệnh để thực hiện chuyển đổi về loại lõi , hoạt động, tuy nhiên giải pháp lập trình sạch để xử lý các loại khác nhau là sử dụng đa hình . Vì đây là Bash, chúng tôi không có tính đa hình mỗi se, nhưng tôi đã loay hoay tìm cách giả mạo nó. Yêu cầu duy nhất là .bashrctập tin của bạn, vv được tổ chức thành các chức năng.

Đầu tiên tôi tạo một thử nghiệm cho loại nền tảng coreutils :

get_coreutils_platform() {
    local ls_version="$(ls --version 2>/dev/null)"
    if [[ "$ls_version" == *"GNU coreutils"* ]]; then
        echo gnu
    else
        echo bsd
    fi
}

Sau đó, chúng tôi có thể gửi dựa trên các loại:

platform=$(get_coreutils_platform)
define_standard_aliases_$platform
configure_shell_vars_$platform

Đây là triển khai BSD :

define_standard_aliases_bsd() {
    define_standard_aliases
}

configure_shell_vars_bsd() {
    configure_shell_vars
    export CLICOLOR=1
}

(Lưu ý chúng tôi sử dụng CLICOLORbiến để bật màu thay vì sử dụng alias, có vẻ như trình dọn dẹp littler)

Và giả mạo GNU :

define_standard_aliases_gnu() {
    define_standard_aliases
    alias ls='ls --color=auto'
}

configure_shell_vars_gnu() {
    configure_shell_vars
}

Để hoàn thiện hơn, đây là một triển khai mẫu của "cơ sở trừu tượng":

define_standard_aliases() {
    alias ll='ls -l'
    alias l.='ls -d .*'
}

configure_shell_vars() {
    export EDITOR=vim
}

Điều này sạch hơn nhiều, trừ khi bạn sử dụng 0,1% hệ thống với ví dụ GNU ls nhưng chưa cài đặt GNU GNU (có thể nó thực sự cũ và chúng có fileutils nhưng không có textutils). Tôi muốn sử dụng lstrong bộ điều phối của bạn hơn là cat, đặc biệt là vì không có bí danh nào của bạn liên quan cat.
Mikel

Ngoài ra, bạn không cần --color=autotrong bí danh thứ hai và thứ ba của mình, vì bí danh thứ nhất thêm tùy chọn đó vào ls.
Mikel

1
@Mikel whoa, tôi hoàn toàn không nhận ra rằng đó aliaslà đệ quy. Điều đó cho phép tôi làm cho ví dụ đơn giản hơn nhiều.
Michael Kropat

Tốt hơn nhiều. :-)
Mikel

0

Không phải là câu trả lời trực tiếp cho câu hỏi của bạn, nhưng tôi có các tập lệnh trình bao bọc để xử lý những việc như thế này thay vì phức tạp thêm trong .bashrc Ví dụ ở đây là tập lệnh l của tôi xử lý trường hợp của bạn ở đây theo cách đa nền tảng:

http://www.pixelbeat.org/scripts/l

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.