추가 인용 없이 bash 변수를 명령으로 정확하게 실행하려면 어떻게 해야 합니까?

추가 인용 없이 bash 변수를 명령으로 정확하게 실행하려면 어떻게 해야 합니까?

문자열로 실행할 명령을 저장해야 하는 스크립트를 만들려고 합니다. 문제의 문자열에는 따옴표가 포함되어야 하며, 이를 실행하려고 할 때 bash는 추가 따옴표 문자를 추가하는데 이로 인해 어떤 경우에는 명령이 예상대로 실행되지 않습니다.

다음은 예제 스크립트입니다. 이 예제 스크립트에서 run 명령은 example분명히 아무 작업도 수행하지 않으며 단순히 다음과 같이 말합니다 . 그러나 실행 중인 정확한 명령이 인쇄되도록 줄 에 command not found추가했기 때문에 스크립트를 실행하고 내가 말하는 내용을 볼 수 있습니다. .-x#!/bin/bash

예:

#!/bin/bash -x

#command typed explicitly
example -options "-i filename"

#command stored in string first
commandstring='example -options "-i filename"'
echo "running command: ${commandstring}"
${commandstring}

이 스크립트를 실행하면 다음과 같은 결과가 나옵니다(두 개의 "명령을 찾을 수 없음" 오류 무시).

+ example -options '-i filename'
+ commandstring='example -options "-i filename"'
+ echo 'running command: example -options "-i filename"'
running command: example -options "-i filename"
+ example -options '"-i' 'filename"'

따라서 명령줄 매개변수를 제공하여 첫 번째 줄이 예상대로 실행되는 것을 볼 수 있습니다.

-i filename

그러나 echo명령이 완벽하게 실행되는 방식으로 문자열을 인쇄하더라도 문자열이 명령줄에 배치되면 문자열이 변경되고 전달되는 매개 변수는 다음과 같이 됩니다.

'"-i' '파일 이름"'

여기에는 추가 인용 문자가 포함되어 있으며 이로 인해 실제 스크립트에서 사용 중인 실제 명령이 실패하게 됩니다.

이를 방지할 수 있는 방법이 있나요?

답변1

를 사용하는 경우 bash명령을 정확하게 저장하는 가장 쉬운 방법은 명령을 배열에 넣는 것입니다. 실행하려는 명령이 다음과 같은 경우:

example -options "-i filename"

다음을 사용하여 배열 변수에 저장할 수 있습니다.

commandline=(example -options "-i filename")

그런 다음 큰따옴표 안에 배열을 @ 확장하여 저장된 명령을 있는 그대로 정확하게 실행할 수 있습니다.

"${commandline[@]}"

여기서 알아야 할 중요한 점은 쉘이 "'\명령줄에 직접 입력할 때 따옴표 문자( )를 에서처럼 변수 확장 내에서 찾을 때와 다르게 처리한다는 것입니다 ${commandstring}. 명령줄에서 따옴표 문자에는 특별한 따옴표 기능이 있습니다. 매개변수 확장 내에서는 특수 문자가 아닌 일반 문자일 뿐입니다. 따라서 는 "-i filename"명령줄에 입력하면 로 구문 분석되는 단일 단어이지만 변수의 동일한 문자는 및 -i filename단어로 확장됩니다 ."-ifilename"


배쉬FAQ 50이 주제를 훨씬 더 자세히 다룹니다.

관련 정보