Bash 스크립트에서 생성된 명령 실행

Bash 스크립트에서 생성된 명령 실행

bash 스크립트에서 이와 같은 명령을 작성했습니다.

a="my_cmd";
a="$a --verbose";
echo $a;
$a;

잘 작동하고 내 명령을 올바르게 실행합니다. 하지만 믹스에 환경 변수를 추가하면 충돌이 발생합니다.

a="my_cmd";
a="URL=myurl $a --verbose";
echo $a;
$a;

"해당 파일이나 디렉터리가 없습니다"로 "URL=myurl"에서 중단되지만 eval()을 사용하여 실행하면 명령이 제대로 작동합니다.

a="my_cmd";
a="URL=myurl $a --verbose";
echo $a;
eval "$a";

두 번째 예에서 환경 변수를 혼합에 추가하면 명령이 중단되는 이유는 무엇입니까?

답변1

변수 확장을 따옴표 없이 그대로 두면분사그리고파일 이름 확장자(즉, 와일드카드). 쉘 명령으로 구문 분석되지 않습니다. 일반적으로 실행될 셸 코드 조각을 동적으로 구성할 때 이를 실행하는 올바른 방법은 셸 코드로 구문 분석할 문자열을 eval "$a"포함하는 것 입니다.a

첫 번째 스니펫에서 값은 astring 입니다 my_cmd --verbose. 두 my_cmd단어 로 나누고 --verbose. 어떤 단어에도 와일드카드가 없기 때문에 와일드카드는 아무 작업도 수행하지 않습니다. 따라서 확장된 명령은 $a두 단어로 구성되므로 명령(별칭, 함수, 내장 명령 또는 PATH의 실행 파일일 수 있음)은 단일 인수로 실행됩니다.my_cmd--verbosemy_cmd--verbose

두 번째 조각에서도 상황은 비슷하며 확장으로 인해 URL=myurl, my_cmd및 3개의 단어가 생성됩니다 --verbose. 이로 인해 URL=myurl두 개의 인수를 사용하여 명령을 실행 하려고 시도하게 됩니다 .

셸 명령 URL=myurl my_cmd --verbose은 다르게 구문 분석됩니다. 첫 번째 단어는 변수에 대한 할당으로 구문 분석 URL되고 그 뒤에 명령 이름이 있으므로 할당은 명령 기간 동안에만 환경 변수를 설정합니다. 이는 확장 후 수행되는 작업이 아니라 구문 분석의 일부이므로 등호가 셸 소스 코드의 일부여야 하며 등호는 일부 확장의 결과일 수 없습니다.

매개변수가 포함된 명령을 문자열에 저장하지 마세요.. 배열을 사용하세요. 명령 실행 외에 변수를 설정하거나 리디렉션을 수행하는 명령과 같은 복잡한 명령의 경우 가능하면 함수를 사용하고 그렇지 않으면 함수를 사용하십시오 eval(올바른 인용에 특히 주의하십시오).

관련 정보