공백이 포함된 파일 이름일 수 있는 선택적 인수를 처리하는 방법

공백이 포함된 파일 이름일 수 있는 선택적 인수를 처리하는 방법

여러 줄로 된 명령 전체를 생략하겠습니다 duplicity. 하지만 다음과 같은 스크립트에서 일련의 매개 변수를 구성하는 것이 가능한지 궁금합니다.

--exclude "$2/${4:-__nosuchfiles__}" --exclude "$2/${5:-__nosuchfiles__}" ...

핵심은 $4, $5...이 이름에 공백이 자주 포함된다는 것입니다. 현재 공식은 작동하지만 __nosuchfiles__제외 기준 세트가 통과 제외 수보다 작은 경우 아무것도 제외하지 않는 추악한 기본값이 희생됩니다 . 누군가가 라는 폴더를 만들 수 __nosuchfiles__있고 처리할 수 있는 제외 항목 수에 제한이 있기 때문에 이것은 약간의 해킹이기도 합니다 .

내가 원하는 건 정의야

EXCLUDES='--exclude "Path 1" --exclude "Path 2"'

내 요구 사항을 충족하는 금액은 --exclude없음에서 많음까지 $EXCLUDES다음과 같은 이중 명령줄로 대체됩니다.

duplicity $STUFF $EXCLUDES $SOURCE $DESTINATION

물론 제외 항목이 공백이 포함된 이름을 지정하는 경우에는 작동하지 않으며 스크립트 자체에서 이러한 제외 항목 집합을 정의하고 사용하기 위한 공식을 작성할 수 없습니다. ( 어떤 대답이라도 전혀 배제하지 않는다는 의미라면 EXCLUDES=""보너스 포인트가 됩니다 .)

예, duplicity's 를 사용할 수 있다는 것을 알고 있지만 --exclude-filelist명령줄이 아닌 파일에서 이름 목록을 편리하게 읽을 수 있는 명령에 의존하지 않는 일반적인 솔루션이 있는지 알고 싶습니다. 또한 $2/제외된 경로의 접두사도 기록해 두십시오.

답변1

중복된 명령줄을 작성하려면 단순한 문자열 연결 대신 배열을 사용해야 합니다. 그런 다음 해당 "${array[@]}"구문을 사용하여 이중성에 대한 별도의(공백 포함) 인수로 배열의 내용을 제공할 수 있습니다. 이렇게 하면 공백이나 기타 특이한 문자를 탈출하는 것에 대해 생각할 필요가 없습니다.

실제로 Duplicity를 호출하지 않고 이것이 어떻게 작동하는지 확인하려면 다음과 같이 인수를 별도의 줄에 인쇄하는 간단한 스크립트를 사용할 수 있습니다.

#!/bin/bash

printf "BEGIN\n"

for x in "$@"
do
  printf "ARG: $x\n"
done

printf "END\n"

으로 저장했습니다 args.sh.

이제 다음과 같이 배열을 사용하여 명령을 작성해야 합니다.

#!/bin/bash

if test -z "$1"
then
  printf "Need at least one argument"
  exit 1
fi

prefix=$1
shift

for arg in "$@"
do
    args+=("--exclude")
    args+=("$prefix/$arg")
done

./args.sh "${args[@]}"

실제로 작동 방식은 다음과 같습니다.

$ ./801811.sh foo bar "baz quux"
BEGIN
ARG: --exclude
ARG: foo/bar
ARG: --exclude
ARG: foo/baz quux
END

$STUFF및 를 고려해야 하므로 이중성 명령줄을 설정하려면 더 많은 작업을 수행해야 하지만 추가하기 전이나 후에 $DESTINATIONargs 배열에 요소를 추가하여 모두 동일한 방식으로 처리할 수 있습니다. args+=("whatever")제외(적절한 경우) 물론입니다). 그리고 마지막에 duplicity "${args[@]}".

답변2

확장이 따옴표 안에 있기 때문에 공백은 여기서 빨간색 청어입니다. 다음과 같이 쉘에서 프로그램을 호출하면:

program "$foo_path/$bar_name"

foo_path무엇이든 포함 하거나 무엇이든 인수를 받습니다 bar_name.

이제 살펴보겠습니다:

--exclude "$2/${4:-__nosuchfiles__}" 

여기서는 비어 있거나 존재하지 않는 경우 전체 매개변수 쌍을 제거하여 4해결책을 찾으려고 합니다.

${4:+--exclude} ${4:+"$2/$4"}

매개 :+변수 대체 연산자가 필요합니다. "비어 있거나 설정되지 않은 경우 아무것도 바꾸지 말고, 그렇지 않으면 대안을 바꿉니다." 이를 --exclude매개변수에 개별적으로 적용합니다.

getopt구현(또는 지원 자체를 해킹)하는 도구를 사용하면 --exclude=ARG둘 다 사용할 수 있습니다 --exclude ARG. duplicity이것이 작동하면 다음과 같이 활용할 수 있습니다.

${4:+"--exclude=$2/$4"}

완전한 데모 프로그램 test.sh:

#!/bin/bash

myargs()
{
  for x in "$@" ; do printf "<%s>\n" "$x"; done
}

myargs ${1:+--foo-opt} ${1:+"x $1 x"}

달리다:

$ ./test.sh
$ ./test.sh ""      # blank treated like missing?
$ ./test.sh abc
<--foo-opt>
<x abc x>
$ ./test.sh "ab c"
<--foo-opt>
<x ab c x>

관련 정보