다음 명령은 결과를 제공하지 않았습니다. grep
파일에서 오류 행을 추출하여 테이블에 삽입하고 싶습니다 .
작동하지 않는 명령:
tail -f logfile.log | grep ERROR|while read msg; do psql -d testdb -c insert into t values('$msg'); done
그러나 grep ERROR
명령에서 코드를 제거하면 예상대로 작동합니다. 무슨 일이 일어났는지 모르겠어요?
잘 작동하는 명령:
tail -f logfile.log|while read msg; do psql -d testdb -c insert into t values('$msg'); done
파일에 다음 데이터가 있다고 가정할 수 있습니다.
ERROR
sql committed
ERROR
ERROR
error
...
답변1
두가지:
질문에 작성된 것처럼
$msg
작은따옴표를 사용했기 때문에 코드는 리터럴 문자열(유효한 경우)을 삽입합니다. 대신 큰따옴표를 사용하세요. 여기에서는 전체 문장을 큰따옴표로 묶었습니다. 그러면 내부가 확장됩니다$msg
. 셸 코드는 여전히 취약합니다 . 이상적으로는 단일 또는 기타 특수 문자로 인해 명령문이 손상되지 않도록(또는 더 나쁜 경우 참조)grep
문자열을 적절하게 삭제해야 합니다.$msg
'
사용자의 의견카스다음과 같은).tail -f logfile.log | grep -F 'ERROR' | while read msg; do psql -d testdb -c "insert into t values('$msg')" done
또한 고정 문자열을 사용하여 검색할 때 호출을 추가했습니다
-F
(주로 문서화 목적입니다).grep
grep
출력 버퍼가 가득 찰 때까지 아무것도 생성되지 않도록 출력을 버퍼링합니다. 이는 실제로는 "작동하지 않는다"는 인상을 주지만grep
출력 버퍼를 플러시할 때까지는 아무 작업도 수행하지 않습니다. 이는 충분한 데이터가 있을 때 수행됩니다. 이는 성능 최적화입니다.GNU
grep
(및 OpenBSD와 같은 동일한 유틸리티의 다른 구현)는--line-buffered
해당 옵션을 통해 라인 버퍼링을 수행할 수 있습니다.tail -f logfile.log | grep --line-buffered -F 'ERROR' | while read msg; do psql -d testdb -c "insert into t values('$msg')" done
참고: 현재 PostgreSQL(?) 인스턴스가 실행되고 있지 않기 때문에 아직 테스트하지 않았습니다.