eval
명령 과 함께 사용하면 eval
명령의 리디렉션 부분에 쉘이 두 번 적용됩니까?
리디렉션의 파일 이름에 공백이 포함되어 있다고 가정할 때 eval
모든 구문 분석, 셸 확장 및 토큰화 단계가 여러 번 적용되면 파일 이름은 두 번째 토큰화 단계에서 두 단어로 분할됩니다.
eval
다음 예는 다음 명령의 리디렉션 부분에 셸이 두 번 적용되지 않으므로 파일 이름이 두 단어로 분할되지 않는다는 의미입니까 ?
$ filename="my file"
$ eval "cat" < "$filename"
hi
답변1
제공한 예에서 유일한 것은 eval
리디렉션 cat
이 외부에서 발생 eval
하고 파일이 명령의 표준 입력으로 제공된다는 것입니다 eval "cat"
.
한 가지 변형은 작은따옴표를 사용하여 리디렉션을 포함하여 전체 명령을 인용하는 것입니다.
$ eval 'cat < "$filename"'
hi
이제 eval
리디렉션 및 변수 이름을 포함한 전체 문자열을 가져오므로 변수 확장은 물론 공백이 포함된 필수 파일 이름 참조도 수행됩니다. 이것은 여전히 작동합니다.
또 다른 옵션은 문자열에 큰따옴표를 사용하는 것입니다.
$ eval "cat < '$filename'"
hi
이제 변수는 셸에 의해 확장되지만 변수 안의 따옴표가 파일 이름을 함께 유지하기 때문에 여전히 작동합니다. (파일 이름에 아포스트로피가 포함되어 있으면 깨질 수 있습니다.)
"작동하지 않는 것"은 다음과 같습니다.
$ eval "cat" "<" "$filename"
이는 귀하의 예와 유사하지만 따옴표를 사용하면 <
외부 쉘이 리디렉션을 수행하지 않습니다. eval
그런 다음 매개변수를 함께 넣으면 결과 명령은 다음과 같습니다.
cat < my file
my file
이제 주변 따옴표가 사라졌기 때문에 예상대로 작동하지 않습니다 .
답변2
작동 방식은 eval
실행할 셸 명령에 매개 변수를 함께 구성하는 것입니다. 변수 이후filename
인용되면 단어 분할이 수행되지 않습니다.언제이것명령은 실행되도록 작성되었습니다.
파일 이름에 공백이 있으면 동일하게 적용되지 않을 수 있으며 따옴표 없이 확장하면 오류가 발생합니다. 예를 들어
filname=my\ file
echo "dude" > my\ file
eval cat < $filename
bash: $filename: ambiguous redirect
여기서 수행된 토큰화와 cat
입력 리디렉션에 대해 잘못된 파일 이름을 수신하여 오류가 발생했다는 점에 유의하세요.
또한 리디렉션 없이 사용하거나 cat
파일에서 직접 사용하는 경우 이 경우 eval
두 개의 파일이 열립니다.cat
eval cat $filename
달리기로 전환됩니다
cat my file
예를 들어, 지정된 파일이 현재 디렉터리에 있으면 해당 내용을 표시하고 지정된 file
파일이 존재하지 않는다는 오류 스트림을 표시합니다.my
filename=my\ file
echo "foo" > file
my
파일을 존재하지 않게 만들고 있습니다.
eval cat $filename 2>&1
cat: my: No such file or directory
foo