배경
실수로 중요한 Python 스크립트를 삭제하여 명령을 실행했습니다.
sudo grep --binary-files=text --context=100 'unique string' /dev/sda1 > recover_file
내 하드 드라이브 에서 검색하여 일치하는 항목을 ./recover_file
. ./recover_file
각 등장 사이에 약간의 쓰레기가 있습니다. 하지만 예상치 못한 동작을 나타내는 이상한 줄이 수백 개 있는데 이에 대해 설명하겠습니다.
나는 줄 번호를 가지고 있습니다. 19행이 파일의 첫 번째 이상한 행인 경우 파일을 열 때 창 하단에 메시지가 표시됩니다.
Conversion error on line 19
처음에 이러한 이상한 줄은 파일에 더 이상 표시할 줄이 없을 때 문서 하단에 나타나는 줄처럼 빈 줄로 나타납니다. ~
창의 맨 왼쪽 가장자리에 문자가 있지만 다른 두 줄 사이에 있습니다. 파일 끝이 아닌 줄:
18 junk junk junk
~
20 junk junk junk
을 사용하여 행 19를 삭제하려고 하면 dd
아무 일도 일어나지 않습니다. 일반 행을 삭제하면 행 19의 모양이 변경되어 다른 빈 행처럼 보입니다.
18 junk junk junk
19
20 junk junk junk
그런데 커서를 그 위로 이동하면 줄 번호가 사라지고 예전처럼 보입니다. 텍스트 삽입이나 추가와 같은 작업을 수행하려고 하면 다음과 같은 결과가 나타납니다.
Error: unable to retrieve line 19
파일을 디스크에 쓰면 다음과 같은 결과를 얻습니다.
Error: recover_file: Invalid or incomplete multibyte or wide character.
recover_file: WARNING: FILE TRUNCATED.
그런 다음 파일을 닫았다가 다시 열면 19행에서 시작하는 모든 행이 삭제되고 1~18행만 남는 것을 볼 수 있습니다. 상황을 재현할 수 있었고 최신 버전의 Python 파일을 새 파일에 복사한 후 추가로 파헤쳐 보니 ./recover_file
분할 오류가 발생하여 전체 파일이 손실되었습니다.
질문
1) 나중에 참고할 수 있도록 중요한 데이터를 잃지 않고 파일을 직접 저장할 수 있도록 이러한 이상한 줄을 제거할 수 있는 방법이 있습니까? 아니면 항상 터미널 창에서 강조 표시하고 복사해야 합니까?
./recover_file
2) 나는 이 동작이 텍스트 문자와 일치하지 않고 Vi가 렌더링할 수 없는 바이너리 코드의 존재로 인해 발생한다고 생각합니다 . 누군가 이 인상을 확인/수정하고 추가 설명을 제공할 수 있다면 감사하겠습니다.
고쳐 쓰다
이것이 관련이 있는지는 잘 모르겠지만 VMware Workstation 14 Player에서 가상 머신으로 lubuntu 18.04를 실행하고 있습니다.
답변1
스크립트를 보면 vi
텍스트 편집기를 사용하여 바이너리를 덤프하고 편집, 검색 및 줄 편집하려고 합니다.
이러한 방식으로 줄 개념, 줄 길이 및 어떤 경우에는 파일 끝 개념까지 뒤집는 많은 제어 문자를 만나게 됩니다.
당신은 텍스트에만 관심이 있고 이미 디스크 내용을 어느 정도 구문 분석했기 때문에 strings
여기에 텍스트가 아닌 문자를 삭제하는 명령을 추가하겠습니다.
vi에서 출력을 처리하려면 스크립트를 다음과 같이 변경할 수 있습니다.
sudo grep --binary-files=text --context=100 'unique string' /dev/sda1 | strings > recover_file
또한 다음과 같이 처음에 이러한 제어 문자를 삭제하는 것이 더 효율적일 것이라고 생각합니다.
sudo strings /dev/sda1 | grep --context=100 'unique string' > recover_file
마지막 명령이 바이너리가 아닌 텍스트로 처리되기 때문에 동일한 결과를 제공할지는 확실하지 않습니다.
~에서man strings
문자열 - 파일에 인쇄 가능한 문자열입니다.
설명하다
주어진 각 파일에 대해 GNU 문자열은 최소 4자 길이(또는 아래 옵션에 제공된 숫자)의 인쇄 가능한 문자 시퀀스와 인쇄할 수 없는 문자를 인쇄합니다. 기본적으로 다른 유형의 파일에 대해서는 대상 파일의 초기화 및 로드 부분에 있는 문자열만 인쇄하고 전체 파일에 있는 문자열을 인쇄합니다.