bash 변수에 공백이 포함된 인용 파일 이름 전달

bash 변수에 공백이 포함된 인용 파일 이름 전달

Bash 셸에서는 다음을 고려하세요.

$ x="-name 'foo bar'"
$ find $x
find: paths must precede expression: `bar''
$ find -name 'foo bar'
./foo bar

그렇게 동작하게 $x하려면 무엇을 넣을 수 있나요 ?find $xfind -name 'foo bar'

답변1

단일 문자열에 별도의 내용( -name및 ) 을 넣지 마십시오 .foo bar

대신 배열을 사용하세요.

args=( -name 'foo bar' )

find . "${args[@]}"

배열 변수 확장에 대한 따옴표는 각 요소가 개별적으로 인용되도록 보장합니다. 이렇게 하면 이것이 foo bar단일 매개변수임을 보장합니다.

위치 매개변수를 사용할 수도 있습니다.

set -- -name 'foo bar'

find . "$@"

다시 말하지만, 인용은 "$@"필수적입니다.

-name 'foo bar'변수를 넣고 따옴표 없이 사용하면 find쉘은 값을 공백, 탭 및 줄 바꿈으로 나눕니다. 이는 find유틸리티가 매개변수 및 를 가져옴 -name'foo의미 합니다 bar'. bar'매개변수를 모르기 때문에 find불평을 합니다.

문자열에 와일드카드 패턴(예: )이 있는 경우 -name '*.txt'쉘은 이를 -name합계 로 분할 '*.txt'한 다음 '*.txt'현재 디렉토리에서 이름을 확장하기 위한 와일드카드 패턴으로 사용됩니다.

답변2

참고: Linux는 find 구문을 지원하지만 보편적이지는 않습니다. 예를 들어, 대부분의 BSD 파생물에서는 작동하지 않으며 다음과 같은 결과를 생성합니다.

bash-3.2$ find -name 'foo bar'
find: illegal option -- n
usage: find [-H | -L | -P] [-EXdsx] [-f path] path ... [expression]
       find [-H | -L | -P] [-EXdsx] -f path [path ...] [expression]

문제는 위치가 아니라 인용과 인용 해석입니다. 코드를 다음으로 바꿀 수 있습니다.

x='foo bar'
find -name "$x"

또는 eval을 사용해 볼 수도 있습니다.

x="-name 'foo bar'"
eval "find $x"

적어도 내 시스템에서는 다음과 같은 결과가 발생합니다.

bash-5.1$ x="-name 'foo bar'"
bash-5.1$ eval "find $x"
./foo bar

나는 이것이 원하는 결과라고 믿는다.

관련 정보