동적 빌드 명령

동적 빌드 명령

스크립트를 작성 중인데 tar명령을 동적으로 작성해야 합니다.

다음은 내가 하려는 작업을 설명하는 두 가지 예입니다.

#!/bin/bash

TAR_ME="/tmp"

EXCLUDE=("/tmp/hello hello" "/tmp/systemd*" "/tmp/Temp*")
_tar="tar "`printf -- '--exclude="%s" ' "${EXCLUDE[@]}"`" -zcf tmp.tar.gz"
echo COMMAND: "${_tar}"
${_tar} "$TAR_ME"

echo -e "\n\nNEXT:\n\n"

EXCLUDE=("--exclude=/tmp/hello\ hello" "--exclude=/tmp/systemd*" "--exclude=/tmp/Temp*")
_tar="tar "`printf -- '%s ' "${EXCLUDE[@]}"`" -zcf test.tar.gz"
echo COMMAND: "${_tar}"
${_tar} "$TAR_ME"

명령 으로 사용할 수 있기를 원하며 _tar클래식 경로에서 작동하도록 만들 수 있었지만 폴더 이름의 공백에서도 작동하려면 필요합니다. 다음 오류가 발생할 때마다:

COMMAND: tar --exclude="/tmp/hello hello" --exclude="/tmp/systemd*" --exclude="/tmp/Temp*"  -zcf tmp.tar.gz /tmp
tar: hello": Cannot stat: No such file or directory

COMMAND: tar --exclude=/tmp/hello\ hello --exclude=/tmp/systemd* --exclude=/tmp/Temp*  -zcf test.tar.gz 
tar: hello: Cannot stat: No such file or directory

당신이 알아야 할 한 가지는 아주 오래된 컴퓨터에서 스크립트를 실행하려면 스크립트가 필요하다는 것입니다. 즉, 최신 bash 기능을 사용할 수 없다는 의미입니다.

답변1

실행 가능한 문자열을 만들려고 하지 마세요. 대신, 배열에 매개변수를 작성하고 호출할 때 이를 사용하십시오 tar(이미 배열을 올바르게 사용하고 있습니다 EXCLUDE).

#!/bin/bash

directory=/tmp

exclude=( "hello hello" "systemd*" "Temp*" )

# Now build the list of "--exclude" options from the "exclude" array:
for elem in "${exclude[@]}"; do
    exclude_opts+=( --exclude="$directory/$elem" )
done

# Run tar
tar -cz -f tmp.tar.gz "${exclude_opts[@]}" "$directory"

그리고 /bin/sh:

#!/bin/sh

directory=/tmp

set -- "hello hello" "systemd*" "Temp*"

# Now build the list of "--exclude" options from the "$@" list
# (overwriting the values in $@ while doing so):
for elem do
    set -- "$@" --exclude="$directory/$elem"
    shift
done

# Run tar
tar -cz -f tmp.tar.gz "$@" "$directory"

$@코드에 대한 참조 sh${exclude[@]}코드에 대한 참조를 참고하세요. 이렇게 하면 목록이 개별적으로 참조되는 요소로 확장됩니다.${exclude_opts[@]}bash

관련된:

답변2

mix(){
        p=$1; shift; q=$1; shift; c=
        i=1; for a; do c="$c $q \"\${$i}\""; i=$((i+1)); done
        eval "${p%\%*}$c${p#*\%}"
}
mix 'tar % -zcf tmp.tar.gz' --exclude "/tmp/hello hello" "/tmp/systemd*" "/tmp/Temp*"

EXCLUDE=("/tmp/hello hello" "/tmp/systemd*" "/tmp/Temp*")
mix 'tar % -zcf tmp.tar.gz' --exclude "${EXCLUDE[@]}"

자세한 답변여기. 이것은 bashism에 의존하지 않으며 데비안 /bin/shbusybox.

관련 정보