sed -i가 /proc/PID/fd/FD와 작동하지 않는 이유

sed -i가 /proc/PID/fd/FD와 작동하지 않는 이유

나는 이 파일과 fd를 가지고 있습니다:exec 88<>abc

$ sed -i "s/cd/II/g" /proc/$$/fd/88
sed: couldn't open temporary file /proc/26194/fd/sedS1D1FT: No such file or directory

하지만 이것은 작동합니다:

$ cat /proc/self/fd/88 | sed  "s/cd/II/g" 
abIIefg

그러면 이것은 작동하지 않습니다.

$ (cat /proc/self/fd/88 | sed  "s/cd/II/g")  > /proc/self/fd/88

/proc/self/fd/88이렇게 하면 비어 있게 됩니다 .

답변1

sed -i파일은 실제로 "그 자리에서" 편집되지 않습니다. 출력을 임시 파일로 리디렉션한 다음 임시 파일의 이름을 바꾸거나 원본 파일로 이동하는 방식으로 작동합니다.

이렇게 하면 도중에 문제가 발생하더라도 원본 파일이 손실되지 않습니다.

더 나쁜 것은 sed(예 vim:) 원본 파일과 동일한 디렉터리에 임시 파일을 만들려고 시도하는 것입니다.

파일 /proc시스템은인조, 그 안에 파일을 만들거나 이동할 수 없기 때문에 해당 오류가 발생합니다. 그러나 sed임시 파일이 에서 생성 되더라도 /tmp마지막 작업(임시 파일을 원본 파일로 이름 바꾸기)은 여전히 ​​실패합니다.

sed -i로터리 방식으로 시도해 볼 수 있습니다 .

$ ised(){ for a; do :; done; t=`mktemp` && sed "$@" > "$t" && cat "$t" > "$a" && rm "$t"; }
$ ised s/cd/II/g /proc/$$/fd/88

파일 이름은 항상 ised.

이는 일관성 보장을 깨뜨립니다 sed -i. 와 달리 cat in > out작업 은 rename("in", "out")원자적이지 않습니다. 중간에 중지되면 out파일이 잘립니다.

답변2

실제 파일이 여전히 존재한다고 가정하면 이것이 더 나을 수도 있습니다(그러나 실제 파일을 수정하므로 주의해서 사용하십시오).

sed -i s/cd/II/g "$(realpath "/proc/$$/fd/88")"

~처럼모스비노트, 의 결과가 realpath /proc/$$/fd/88삭제된 경우 이 작업은 아무런 효과가 없습니다. 예:

exec 7>/tmp/junk; echo yes >&7; rm /tmp/junk; 
cat /proc/$$/fd/7; cat "$(realpath "/proc/$$/fd/7")"

출력(에도 불구하고/tmp/정크존재하지 않음), 첫 번째 줄표준 출력, 라인 2 ~표준 오류 오류율:

yes
cat: '/tmp/junk (deleted)': No such file or directory

관련 정보