스크립트에서 systemctl status
출력을 처리하는 이상한 방법을 발견했습니다.
echo "$(systemctl status the_unit_name)" | grep -q 'Active: active'
명백한 것보다는:
systemctl status the_unit_name | grep -q 'Active: active'
이 접근 방식을 사용해야 할 타당한 이유를 찾을 수 없습니다. 제가 빠진 이유가 있나요?
답변1
systemctl
(주변 설정에 따라) 무시될 수 있는 종료 상태 외에 다른 이유는 없습니다. 왜 명령을 이렇게 썼는지 설명하는 역사적 요인이 있을 수 있지만, 이렇게 유지할 이유는 없습니다.
당신은 또한 볼 수 있습니다서비스가 스크립트에서 실행 중인지 테스트하는 "올바른" 방법.
답변2
일반적으로 말해서, echo "$(foo)"
는 멍청하고 just 와 거의 동일합니다 foo
. 차이점은 명령 대체는 출력에서 모든 후행 줄 바꿈을 제거 foo
하고 echo
정확히 하나만 추가한다는 것입니다(그리고 백슬래시를 처리할 수 있지만 그렇지 않다고 가정합니다). 일반적으로 출력은 정확히 1이 될 가능성이 높기 때문에 아무것도 변경되지 않습니다.
하지만출력에 foo
마지막 개행 문자가 누락된 경우 echo
의미와 명령 대체를 조합하여 파이프의 오른쪽이 올바른 텍스트 파일을 입력으로 가져오도록 하여 문제를 해결할 수 있습니다. 이는 원칙적으로 중요합니다. 기술적으로 POSIX 표준에서는 입력이 올바른 텍스트 파일이어야 하고, 그렇지 않은 경우 예상치 못한 동작이 발생할 수 있기 때문입니다.
grep
실제로 이러한 구현에서 기술적으로 유효하지 않은 입력으로 인해 문제가 발생하거나 줄 바꿈이 없는 최종 라인 세그먼트를 다른 라인과 다르게 처리하는 것을 본 적이 없습니다 . grep의 작동 방식을 고려하면 기본적으로 줄바꿈을 무시하고 명확하지 않은 동작이 쉽게 발생할 수 있습니다. (또한 fgets()
줄 읽기를 위한 C 표준 함수는 read
종료 상태가 줄 바꿈이 표시되는지 여부에 따라 달라지는 쉘의 와 달리 끝에 줄 바꿈이 있는지 여부를 실제로 신경 쓰지 않습니다. 그런 다음 유틸리티가 다음을 확인하지 않는 경우에도 마찬가지입니다. it 읽고 있는 내용은 끝에 줄 바꿈이 있어야 한다고 가정하고 무조건 마지막 문자를 제거합니다. 예를 들어 buf[strlen(buf) - 1] = '\0'
마지막 줄 바꿈이 없으면 마지막 일반 문자를 먹습니다.
즉, 나는 그것이 실제로 그들이 이상해 보이는 명령을 실행한 이유라고 믿지 않습니다. (그리고 나는 그것이 잘못된 결과를 낳을 것이라고 생각하지 않습니다 systemctl
.) 아마도 그들은 자신이 하고 있는 일에 대해 실제로 생각하지 않았을 것입니다.