"동일한 파이프에서 동일한 파일을 읽고 쓰지 않도록 주의하세요"

"동일한 파이프에서 동일한 파일을 읽고 쓰지 않도록 주의하세요"

쉘체크 보고서:

echo -e "blah/blah\n$(cat "$tmpdir"/"$filename".jpdf)" > "$tmpdir"/"$filename".jpdf
                          ^-- SC2094: Make sure not to read and write the same file in the same pipeline.
                                                         ^-- SC2094: Make sure not to read and write the same file in the same pipeline.

blah/blah이 명령의 목적은 파일 시작 부분에 줄을 삽입하는 것입니다 "$tmpdir"/"$filename".jpdf.

"동일한 파이프에서 동일한 파일을 읽고 쓰지 않도록 하십시오"라는 것은 무엇을 의미합니까?

어떻게 해야 하나요?

감사해요.

답변1

다른 답변에서 지적했듯이 동일한 파일을 읽고 쓰면 파일이 지워진다는 경고가 표시됩니다. 그 이유는 >입력이 완료되기 전에 파일이 잘리기 때문입니다.

두 가지 선택이 있습니다.

  1. sponge포장을 제거하고 사용하세요 moreutils. sponge다음 명령으로 파이프되기 전에 입력이 완전히 소비되었는지 확인합니다.

    바꾸다

    command "$file" > "$file"
    

    하다

    command "$file" | sponge "$file"
    
  2. 출력을 다른 파일로 리디렉션하고 이름을 바꿉니다.

    이와 같이

    command "$file" > "$file2" && mv "$file2" "$file"
    

특정 질문과 관련하여 파일에 "어쩌고 저쩌고"를 추가하면 sed해당 옵션이 지원되는 경우 -i작동합니다 . 예를 들어 GNU sed:

sed '1i\
blah/blah' -i "$file"

답변2

그것은 가장 문자 그대로의 의미로 말하는 것을 정확히 의미합니다. 이 명령이 실제로 수행하는 작업은 파일을 덮어쓰고 $tmpdir/$filename.jpdf한 줄만 에코하는 것입니다. 쉘은 리디렉션을 확인한 다음 파일을 자르고 쓰기 위해 엽니다. 그런 다음 명령을 실행하여 (새) 콘텐츠를 생성하기 시작합니다. 당신이 해야 할 일은 새 내용을 다른 파일에 쓴 다음 두 번째 명령에서 새 파일을 이전 이름으로 복사하는 것입니다.

답변3

더 간단한 명령줄을 입력해 보겠습니다.

cat file > file

파일에 데이터가 포함되어 있으면 삭제됩니다. 다음을 시도해 보세요.

$ echo "content of file" > file
$ cat file
content of file

$ cat file > file

$ cat file
                     # empty file.

쉘은 명령을 실행하기 전에 리디렉션을 처리합니다.
처리하는 동안 쓰기 잘림을 위해 >file열립니다 file.
그 이후에는 파일이 비어 있습니다.
이 명령은 cat빈 파일에 대해 cat 작업을 수행하고 아무것도 쓰지 않습니다.

관련 정보