줄 끝의 백슬래시가 너무 많은 공간을 차지하는 이유는 무엇입니까?

줄 끝의 백슬래시가 너무 많은 공간을 차지하는 이유는 무엇입니까?

나는 생각했다:

#!/bin/bash
cmd --options \
    option=value,\
    option=value,\
    option=value,\
    option=value

그러나 그것을 실행한 후에는 다음과 같은 bash -x결과를 얻습니다.

cmd --options option=value, option=value, option=value, option=value

이로 인해 오류가 발생합니다.

Bash가 자동으로 이 공간을 넣지 않도록 하려면 어떻게 해야 합니까?

답변1

음, 각 줄의 시작 부분에는 공백이 있습니다. 단일 공간으로 압축되었더라도 bash는 이를 자동으로 제거하지 않습니다.

이를 완전히 피하려면 다음과 같이 스크립트를 작성하십시오.

#!/bin/bash
command --options \
opt1=val1,\
opt2=val2,\
opt3=val3

답변2

문자열을 명령에 단일 인수로 전달 해야 opt1=val1,opt2=val2,...하지만 편집 가능성을 위해 스크립트의 여러 줄에 걸쳐 분산시키려는 경우 배열을 중간 단계로 사용한 다음 명령을 실행할 때 모든 배열 요소를 연결할 수 있습니다. 명령.

예를 들어

opts=(
    opt1=val1    # no commas here 
    opt2=val2    # but comments also work
    etc.
)
(IFS=,
 echo somecmd --options "${opts[*]}"   # echo for demonstration
)

그런 다음 인쇄somecmd --options opt1=val1,opt2=val2,etc.

(첫 번째 대괄호 쌍은 배열 할당 구문의 일부이고 두 번째 쌍은 스크립트의 나머지 부분이 수정되지 않도록 보호하기 위해 하위 쉘을 시작합니다 . 특히 스크립트가 이후에 아무 작업도 수행하지 않거나 재설정 IFS하는 경우에는 이 하위 쉘이 필요하지 않을 수 있습니다. IFS나중에 사용하거나 전혀 사용하지 마세요).

분명히 이를 위해서는 배열을 지원하는 기능이 풍부한 셸이 필요합니다. Bash 외에도 zsh도 사용할 수 있습니다. ksh에서는 문자열(또는 적어도 등호)을 인용해야 구조체와 같은 것으로 바뀌지 않습니다.복합변수.


POSIX sh 호환 솔루션이 필요한 경우 배열과 가장 가까운 것은 위치 인수 목록이지만 그 중 하나의 세트만 있고 set일반 명령과 어느 정도 작동하므로 다음 사항을 기억해야 합니다. 백슬래시 바(그리고 주석은 사용할 수 없습니다).

대신 다음과 같이 작동해야 합니다.

args=$( <<EOF sed -e 's/^[[:space:]]*//' | tr '\n' ,
    opt1=val1
    opt2=val2
    etc.
EOF
)
args=${args%,}
echo somecmd --options "$args"  # echo for demonstration

답변3

또 다른 옵션:

#!/bin/bash
cmd --options "$(printf "%s" \
    "option=value," \
    "option=value," \
    "option=value," \
    "option=value"
)"

printf "%s"공백 없이 인수를 인쇄하므로 결과는 다음과 같습니다.

cmd --options option=value,option=value,option=value,option=value

일부 명령은 단일 인수로 전달되는 한 자체적으로 공백을 완전히 제거할 수도 있습니다. 따라서 간단한 인용(단어 분리를 방지하기 위해)이면 충분합니다. 예를 들어 ffmpeg다음과 같습니다.

ffmpeg -i somefile.mp4 -vf "
    hflip,
    vflip,
    hue=s=0
" result.mp4

그러나 사용하는 명령이 이러한 옵션을 처리하는 방법에 따라 다릅니다.

작동하지 않는 경우를 대비해 잠재적으로 여러 번 사용할 수 있는 옵션도 있지만 --options(명령에서 허용하는 경우) ffmpeg때로는 괜찮습니다.

답변4

각 옵션을 한 줄에 배치하려면 다른 접근 방식을 시도해 볼 수 있습니다.

options="opt1=val1,"
options+="opt2=val2,"
options+="opt3=val3"
your_command --options "${options}"
# note: "command" being a bash builtin, I replaced it by "your_command"
# (command foo : bypasses any alias/function "foo" and instead launches "foo" from $PATH)

관련 정보