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_4STOP_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"단어 분리를 방지해야 합니다.공백이나 기타 특수 문자 때문에 쉘 스크립트가 멈추는 이유는 무엇입니까?

때를수동명령을 입력할 때 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")"

관련 정보