쉘 설정 스크립트에서 GNU와 비교하여 BSD에서 coreutils의 차이점을 어떻게 설명 할 수 있습니까?


9

이번 달까지 쉘 구성은 꽤 단순 했지만 (주로 별명 .bashrc또는 .bash_profile일부 별칭 사용), 리팩토링하여 zsh 및 bash 사용 여부에 따라 다른 동작을 얻을 수 있습니다. 그들은 먼저 무엇이든 작동하는 일반 쉘 구성 파일을 제공 한 다음 사용중인 특정 쉘을 전문화합니다 (I symlink to this).

나는 일을 ls그만두 었을 때 오늘 놀랐다 . 리팩토링하는 동안 .bashrc별칭이 있음이 밝혀졌습니다.

alias ls='ls --color=always'

그 위해 물건을 깨는했다 lsOSX 터미널에서 떠들썩한 파티에서. BSD ls-G색상을 좋아 하지만 GNU (또는 Ubuntu에있는 것이 무엇이든) 좋아 --color한다는 것을 알았을 때, 몇 가지 옵션이 다르다는 것이 분명했습니다.

내 질문은 옵션과 BSD와 GNU coreutils의 차이점을 설명하는 가장 좋은 방법은 무엇입니까? if사용중인 OS를 확인하고 올바른 동작을 적용하기 위해 블록 에서 env 변수를 테스트해야합니까 ? 아니면 각 OS에 대해 별도의 구성 파일을 만드는 것이 더 합리적입니까?

이러한 질문에 대한 대답은 주관적 일 수 있지만, BSD와 GNU coreutils의 차이점에 대한 요약과 대부분의 * nix에서 일반 구성을 사용할 수 있도록하기 위해이를 해결하는 전략은 상당히 객관적입니다.


쉘을 변경해도 아무것도 수정되지 않으며와 ls -c다릅니다 ls --color. 수정하기 위해 질문을 수정했습니다.
Mikel

답변:


9

다른 운영 체제를 지원하는 스크립트를 작성하는 신뢰할 수있는 유일한 방법은 POSIX에서 정의한 기능 만 사용하는 것입니다.

개인 셸 구성과 같은 경우 특정 사용 사례에 맞는 핵을 사용할 수 있습니다. 다음과 같은 것은 추악하지만 목표를 달성 할 것입니다.

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

나는 다른 방법으로 놀고 있었고, 당신의 "추악한"솔루션은 꽤 좋고 추악하지도 않다고 생각합니다. 결과적으로 포트에서 GNU coreutils를 사용하고 있었기 때문에 ls의 옵션이 일치하지 않는 것으로 나타났습니다. 이것이 $ OSTYPE에서 'if'를 수행하는 것이 원하는 결과를 제공하지 못하는 이유의 예입니다.
labyrinth

GNU coreutils가 없을 때 (하지만 여전히 coreutils를 테스트 할 수있는 경우) "if ls --version"에서 발생하는 오류를 억제하는 방법이 있습니까?
미로

오, 오류를 억제하는 것에 대해 신경 쓰지 마십시오. grep에 파이핑하기 전에 stderr을 / dev / null로 리디렉션하면 원하는대로 작동합니다.
미로

3
coreutils명시 적으로 찾기보다는 색상 플래그가 작동하는지 테스트하지 마십시오 (예 :) if ls --color=auto -d / >/dev/null 2>&1; then ....
Mikel

@ mikel (예와 같이) 색상에만 관심이 있다면 괜찮습니다. 다른 기능도 관심이 있다면 coreutils를 확인하는 것이 유용합니다.
jordanm

3

coreutilsif 유형에 대한 스위치를 수행하기 위해 명령문을 코드 에 담그면 작동하지만 다른 유형을 처리하기위한 깨끗한 프로그래밍 솔루션은 다형성 을 사용하는 것 입니다. 이것은 Bash이므로 다형성 자체는 없지만 가짜 방법으로 엉망이되었습니다. 유일한 요구 사항은 .bashrc파일 등을 기능으로 구성하는 것입니다.

먼저 coreutils 플랫폼 유형에 대한 테스트를 만듭니다 .

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

그런 다음 유형에 따라 발송할 수 있습니다.

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

BSD 구현 은 다음과 같습니다 .

define_standard_aliases_bsd() {
    define_standard_aliases
}

configure_shell_vars_bsd() {
    configure_shell_vars
    export CLICOLOR=1
}

(우리는 CLICOLOR변수를 사용하여 좀 alias더 깨끗한 것처럼 보이는 대신 색을 켭니다. )

그리고 GNU 함축 :

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

configure_shell_vars_gnu() {
    configure_shell_vars
}

완전성을 기하기 위해 다음은 "추상베이스"의 샘플 구현입니다.

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

configure_shell_vars() {
    export EDITOR=vim
}

GNU ls가 설치되어 있지만 GNU cat이 설치되어 있지 않은 시스템의 0.1 %가 아닌 경우 (이것은 실제로 오래되어서 파일 유틸리티는 있지만 textutils는없는 경우) 훨씬 깨끗합니다. 특히 별명과 관련이 없기 때문에 ls디스패처에서 사용하고 싶습니다 . catcat
Mikel

또한 --color=auto첫 번째 별칭이 해당 옵션을에 추가하므로 두 번째 및 세 번째 별칭 에는 필요하지 않습니다 ls.
Mikel

1
@Mikel whoa, 나는 그것이 alias재귀 적임을 전혀 몰랐습니다 . 이를 통해 예제를 훨씬 간단하게 만들 수 있습니다.
Michael Kropat

훨씬 낫다. :-)
Mikel

0

귀하의 질문에 대한 직접적인 대답은 아니지만 .bashrc의 추가 합병증보다는 이와 같은 것을 처리하는 래퍼 스크립트가 있습니다. 예를 들어 여기에 크로스 플랫폼 방식으로 귀하의 사례를 처리하는 l 스크립트가 있습니다.

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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.