Bash 스크립트에서 공백을 사용하여 여러 매개변수 반복

Bash 스크립트에서 공백을 사용하여 여러 매개변수 반복

omxplayer내 RaspberryPi(Raspbian 실행)에 여러 파일 이름을 인수로 사용하여 하나씩 재생(사용)하는 bash 스크립트가 있습니다 . 기본 구조는 다음과 같습니다.

#!/bin/bash
for f in ${*}
do
  echo "${f}";
done;

이제 입력 파일 이름에 공백이 포함되어 있으면 문제가 발생합니다. 특히 동작이 일관되지 않은 것 같습니다. 두 개의 파일이 test a b있고 test d e동일한 디렉토리에 있다고 가정해 보겠습니다 . 다른 매개변수를 사용하여 위 스크립트를 실행하면 다음과 같은 결과가 생성됩니다.

$ ./test test\ a\ b
test
a
b
$ ./test "test a b"
test
a
b
$ ./test test\ a*
test
a
b
$ ./test "test a*"
test
a*

그런데 이상한 점은 다음과 같습니다.

./test "test*"
test a b
test d e

분명히 마지막 변형만이 예상되는 출력을 제공합니다. 그러나 특히 단일 파일을 보려는 경우(탭 완성으로 전체 이름이 채워짐) 파일 경로의 폴더 이름 중 하나에 공백이 포함된 경우에는 사용하기가 번거롭습니다.

항상 예상대로 실행되도록 쉘스크립트에서 다르게 수행할 수 있는 작업은 무엇입니까? 특히, 둘 다

$./test test*
$./test test\ a\ b test\ d\ e

동일한 출력을 생성해야 합니다.

test a b
test d e    

따라서 일반적인 탭 완성을 사용하여 스크립트를 쉽게 사용할 수 있습니다.

답변1

"$@"대신 사용하세요 ${*}(참조특수 매개변수설명서에 있음)

for f in "$@"; do 
    echo make sure you quote your "$variables" everywhere in the loop

속기가 있습니다 (그리고 더 이식 가능합니다):

for f do ...

for f; do일부 쉘에서도 작동하지만 표준은 아닙니다.

답변2

while또 다른 접근 방식은 다음 두 가지 방법 중 하나로 루프를 사용하는 것입니다.

input_cmd|while read i; do
  echo "$i";
done

또는 다음 절차를 통해 교체하십시오.

while read i; do
  echo "$i";
done < <(input_cmd)

내가 아는 한, 후자는 bashism이므로 다른 Bourne 호환 쉘에서는 작동하지 않을 수 있습니다.

그러나 명령줄에서 입력을 받기 때문에 for이전 답변에서 제공된 루프 솔루션을 고수하는 것이 가장 좋습니다.

man xargs또한 외부 명령줄 인수를 처리하는 가장 좋은 방법인 경우도 있으므로 살펴보아야 합니다 .

관련 정보