Bash 문자열 평가가 불분명함

Bash 문자열 평가가 불분명함

Bash 스크립트에서 다음을 고려하십시오.

STOP_SEARCH_STR="'""for $TASKNAME""'"
echo $STOP_SEARCH_STR               # prints 'for Our Special Task_4'
echo "$STOP_SEARCH_STR"             # prints 'for Our Special Task_4'
echo "grep -F "$STOP_SEARCH_STR" "$TEMP"/draft" # prints grep -F 'for Our Special Task_4' /tmp/draft
echo "$(grep -F "$STOP_SEARCH_STR" "$TEMP"/draft)"  # prints nothing!
echo $("grep -F "$STOP_SEARCH_STR" "$TEMP"/draft")  # prints nothing!

$TEMP/draft 텍스트 파일에는 다음 내용이 포함됩니다.

2019-11-21 08:13:58,825 Task started: 'Our Special Task_4' of type 'Our - Special Task' 
2019-11-21 08:14:10,509 Task ended: 'Success' for Our Special Task_4 -- Elapsed time: 11.0 seconds

만약 내가수동으로명령을 입력하면 grep -F 'for Our Special Task_4' /tmp/draft초안 텍스트 파일에 두 번째 줄이 표시됩니다.

2019-11-21 08:14:10,509 Task ended: 'Success' for Our Special Task_4 -- Elapsed time: 11.0 seconds

그러나 위의 마지막 2개 명령(bash 스크립트 내부)은 아무것도 인쇄하지 않습니다!

왜 그런지 아시나요?

답변1

변수가 확장된 후에는 따옴표가 특별하지 않습니다.

TASKNAME포함한다고 가정 Our Special Task_4하면 해당 따옴표를 포함하여 STOP_SEARCH_STR로 설정됩니다 . 'for Our Special Task_4'그게 바로 당신의 echo쇼입니다.

을 실행하면 찾을 문자열이 grep -F "$STOP_SEARCH_STR" "$TEMP"/draft제공됩니다 . 해당 문자열은 파일에 존재하지 않으므로 일치하는 행이 없으며 아무것도 인쇄되지 않습니다.grep'for Our Special Task_4'grep

따옴표를 제거하면 찾고 있지 않습니다.

task="Our Special Task_4"
str="for $task"
grep -F "$str" "$TEMP/draft"

참고: 당신하다변수 확장 주위에 큰따옴표가 필요 "$str"하거나 "$STOP_SEARCH_STR"단어 분할을 방지하려면 다음을 참조하세요.쉘 스크립트가 공백이나 기타 특수 문자로 인해 막히는 이유는 무엇입니까?

때를수동으로command 를 입력하면 grep -F 'for Our Special Task_4' /tmp/draft따옴표는 셸 구문의 일부이며 그 안의 공백의 특별한 의미를 효과적으로 제거합니다. 이는 일반 문자처럼 작동하는 변수 내부의 따옴표와 다릅니다.


여담으로: 1) echo "$(somecmd)"일반적으로 중복되므로 직접 실행할 수 있습니다 somecmd. 2) 여기에서는 echo $("grep -F "$STOP_SEARCH_STR" "$TEMP"/draft")따옴표가 공백을 둘러싸는 방식 때문에 이라는 명령을 실행하려고 합니다 grep -F 'for. 아마도 다음과 같은 오류가 발생했을 것입니다.

$ echo $("grep -F "$STOP_SEARCH_STR" "$TEMP"/draft")
bash: grep -F 'for: command not found

답변2

다음 줄을 변경해야 합니다.

STOP_SEARCH_STR="'""for $TASKNAME""'"

이 줄에 추가합니다(예, 작은따옴표는 필요하지 않으며 유용하지 않습니다).

STOP_SEARCH_STR="for $TASKNAME"

그리고 스크립트에서 다음 줄을 사용하세요(예, 표시된 대로 인용됨).

grep -F "$STOP_SEARCH_STR" "$TEMP"/draft

에코를 추가하고 싶거나 필요하다면(과잉이고 문제를 일으킬 수도 있음) 다음 행을 사용하십시오(예, 모든 확장(변수 및 하위 쉘)을 인용하십시오):

echo "$(grep -F "$STOP_SEARCH_STR" "$TEMP"/draft")"

관련 정보