Nos scripts de configuração do shell, como posso explicar as diferenças entre os coreutils no BSD em comparação com o GNU?

9

Até este mês, minhas configurações de shell foram bem simples (apenas um .bashrc ou .bash_profile com alguns aliases principalmente), mas tenho refatorado para poder ter um comportamento diferente, dependendo se estou usando zsh e bash. Eles primeiro fonte um arquivo de configuração de shell genérico que deveria trabalhar para qualquer, então especialize para o shell específico que está sendo usado (eu symlink a isto).

Fiquei surpreso hoje quando ls parou de funcionar. Descobriu-se que durante a refatoração .bashrc , havia um alias

alias ls='ls --color=always'

que estava quebrando as coisas para ls no bash no Terminal no OSX. Uma vez que vi que o BSD ls gosta de -G para cores, mas o GNU (ou o que quer que estivesse no Ubuntu) gosta de --color , ficou claro que algumas opções são diferentes.

A minha pergunta é, qual é a melhor maneira de explicar as diferenças nas opções e entre o BSD e o GNU coreutils? Devo testar uma variável env em if blocos para ver qual sistema operacional está sendo usado e aplicar o comportamento correto? Ou faz mais sentido criar arquivos de configuração separados para cada SO?

Embora as respostas a essas perguntas possam ser subjetivas, parece que um resumo do escopo das diferenças entre o BSD e o GNU coreutils e as estratégias para contornar isso para tornar uma configuração genérica utilizável na maioria dos * nix seria bastante objetiva.

    
por labyrinth 07.12.2013 / 05:55

3 respostas

8

A única forma confiável de escrever scripts que suportam diferentes sistemas operacionais é usar apenas recursos definidos pelo POSIX.

Para coisas como suas configurações pessoais de shell, você pode usar hacks que se encaixam em seu caso de uso específico. Algo como o seguinte é feio, mas vai cumprir o objetivo.

if ls --version 2>/dev/null | grep -q 'coreutils'; then
    alias ls='ls --color=always'
else
    alias ls='ls -G'
fi
    
por 07.12.2013 / 06:26
3

Lixeira do código com if declarações para executar um switch no tipo de coreutils funciona, no entanto, a solução de programação limpa para lidar com diferentes tipos é usar polimorfismo . Como esse é o Bash, não temos polimorfismo em si, mas ando brincando com um jeito de fingir. O único requisito é que o seu arquivo .bashrc seja organizado em funções.

Primeiro, crio um teste para o tipo de plataforma coreutils :

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

Em seguida, podemos enviar com base no tipo:

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

Aqui está a implementação do BSD :

define_standard_aliases_bsd() {
    define_standard_aliases
}

configure_shell_vars_bsd() {
    configure_shell_vars
    export CLICOLOR=1
}

(Observe que usamos a variável CLICOLOR para ativar cores em vez de usar um alias , que parece um limpador menor)

E a impelementação do GNU :

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

configure_shell_vars_gnu() {
    configure_shell_vars
}

Para fins de integralidade, aqui está uma implementação de exemplo da "base abstrata":

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

configure_shell_vars() {
    export EDITOR=vim
}
    
por 18.03.2014 / 12:49
0

Não é uma resposta direta à sua pergunta, mas eu tenho scripts de wrapper para lidar com coisas como esta ao invés de complicação extra no .bashrc Por exemplo, aqui está meu script l que lida com o seu caso aqui de uma maneira multiplataforma:

link

    
por 18.03.2014 / 16:03