대체 명령으로 첫 번째 명령과 동일한 매개변수를 사용하여 두 번째 명령을 실행합니다.

대체 명령으로 첫 번째 명령과 동일한 매개변수를 사용하여 두 번째 명령을 실행합니다.

다음 명령을 실행하고 싶습니다.

tar  --sort=name --owner=root:0 --group=root:0 --mtime='UTC 2020-01-01' -cvf api.tar api

그러나 macOS에는 다음과 같은 대체 조치가 필요합니다.

gtar --sort=name --owner=root:0 --group=root:0 --mtime='UTC 2020-01-01' -cvf api.tar api

(참고: 매개변수는 동일합니다.)

gtar먼저 호출한 다음 tar폴백으로, 한 줄로 매개변수를 한 번만 쓸 수 있나요 ?

답변1

먼저 gtar를 호출한 다음 대체 수단으로 tar를 한 줄로 호출하고 매개변수를 한 번만 쓸 수 있나요?

이 질문에 대답하려면 다음과 같이 하십시오. 이는 매개변수를 배열에 저장하는 간단한 구현으로 수행할 수 있습니다. (Bash/ksh/zsh. 참조변수에 저장된 명령을 어떻게 실행할 수 있나요?문제와 POSIX 호환 해결 방법에 대해 알아보세요. )

args=(--sort=name --owner=root:0 --group=root:0 --mtime='UTC 2020-01-01' -cvf api.tar api)
if ! tar "${args[@]}"; then
    echo "using 'tar' failed, retrying with 'gtar'" >&1
    gtar "${args[@]}"
fi

또는 다음과 같이 주장한다면 한 줄로:

tar "${args[@]}" || gtar "${args[@]}"

이게 설명이 안 되긴 하지만문제가 액세스할 수 없는 디렉토리와 유사하더라도 실패하고 다른 tar로 다시 시도합니다.

또 다른 옵션은 첫 번째 명령에서 "명령을 찾을 수 없음" 오류가 발생하면 명령을 다시 실행하는 것입니다. $?이 경우 쉘은 일반적으로 127로 설정됩니다. 물론 이것은 아마도 어떤 형태로든 존재할 것이기 gtar때문에 먼저 뒤집어 야 합니다.tar

gtar "${args[@]}"
ret=$?
if [ "$ret" = 127 ]; then
    tar "${args[@]}"
    ret=$?
fi

테스트에서는 [ "$? = 127 ]값을 삭제하므로 $?실제 종료 상태를 유지하려면 추가 변수가 필요합니다.

두 개의 타르가 있는 특별한 경우에는,코살로난다의 답변미리 확인해 보는 것도 좋은 해결책이다.

답변2

tarmacOS에서 Homebrew 설치 프로그램을 사용하여 GNU를 설치한 경우 gnu-tar터미널에 다음 메시지가 표시됩니다.

GNU "tar" has been installed as "gtar".
If you need to use it as "tar", you can add a "gnubin" directory
to your PATH from your bashrc like:

    PATH="/usr/local/opt/gnu-tar/libexec/gnubin:$PATH"

즉, 위의 설치 메시지와 같이 먼저 tar설정을 하면 질문 시작 부분의 명령이 예상대로 작동한다는 뜻입니다.PATHgnu-tar

PATH="/usr/local/opt/gnu-tar/libexec/gnubin:$PATH"
tar  --sort=name --owner=root:0 --group=root:0 --mtime='UTC 2020-01-01' -cvf api.tar api

조건부 업데이트 PATH:

if [ "$(uname)" = Darwin ]; then
    PATH="/usr/local/opt/gnu-tar/libexec/gnubin:$PATH"
fi

tar  --sort=name --owner=root:0 --group=root:0 --mtime='UTC 2020-01-01' -cvf api.tar api

다음을 사용하여 테스트할 수도 있습니다 command -v.

if command -v gtar >/dev/null 2>&1; then
    tar=gtar
elif command -v tar >/dev/null 2>&1 && tar --version | grep -q -F GNU 2>/dev/null; then
    tar=tar
else
    echo 'No GNU tar available' >&2
    exit 1
fi

"$tar" --sort=name --owner=root:0 --group=root:0 --mtime='UTC 2020-01-01' -cvf api.tar api

gtar명령으로 존재하는지 테스트합니다 . 그렇다면 변수는 tarstring 으로 설정됩니다 gtar. 존재하지 않으면 테스트하고 tar, 존재하는 경우 하위 문자열을 포함하는 항목이 반환되는지 tar테스트하고 해당 문자열을 변수에 할당합니다 . 그러나 테스트가 실패하면 진단 메시지와 함께 종료됩니다.tar --versionGNUtartar

나중에 오류 메시지와 함께 종료하지 않으면 "$tar"as 명령을 사용합니다.

uname분명히 다음의 출력을 테스트하도록 선택할 수도 있습니다.

if [ "$(uname)" = Darwin ]; then
    # Assumes GNU tar is gtar on macOS and that it's available
    tar=gtar
else
    # Assumes GNU tar is tar on this system, and that it's available
    tar=tar
fi

"$tar" --sort=name --owner=root:0 --group=root:0 --mtime='UTC 2020-01-01' -cvf api.tar api

관련 정보