파일을 인수로 받아들이고 파일을 수정한 다음 두 번째 인수에 지정된 파일 이름에 쓰는 명령이 있습니다. 나는 이 프로그램을 이라고 부를 것이다 modifyfile
.
나는 그것이 "제자리에서" 작동하기를 원했기 때문에 임시 파일로 수정한 다음 다시 옮기는 쉘 스크립트(bash)를 작성했습니다.
TMP=`mktemp`
modifyfile "$original" "$TMP"
mv -v "$TMP" "$original"
불행하게도 이로 인해 파일에 대한 권한이 손상됩니다. 파일은 기본 권한으로 다시 생성됩니다.
mv
권한을 변경하지 않고 대상을 덮어쓰도록 명령에 지시하는 방법이 있습니까 ? 아니면 원래 사용자, 그룹 및 권한을 저장하고 복원하는 방법이 있습니까?
답변1
사용되지 않고 mv
리디렉션만 됩니다 cat
. 예를 들어:
TMP=$(mktemp)
modifyfile "$original" "$TMP"
cat "$TMP" > "$original"
이렇게 하면 파일 수준에서 아무 것도 건드리지 않고 $original
내용을 덮어씁니다 .$TMP
답변2
파일을 새 버전으로 바꾸는 두 가지 전략이 있습니다.
새 버전으로 임시 파일을 만든 다음 해당 위치로 이동합니다.
- 장점: 프로그램이 파일을 열면 이동 전이나 후에 파일을 열었는지에 따라 이전 내용이나 새 내용을 읽습니다. 혼란이 없습니다.
- 장점: 충돌이 발생하면 오래된 콘텐츠가 유지됩니다.
- 단점: 새 파일이 생성되므로 파일의 속성(소유권, 권한 등)이 유지되지 않습니다.
이전 파일을 제자리에 덮어씁니다.
- 장점: 파일 속성을 유지합니다.
- 단점: 충돌이 발생하면 파일이 절반만 기록될 수 있습니다.
- 단점: 파일이 업데이트되는 동안 프로그램이 파일을 열면 프로그램이 일관되지 않은 데이터를 읽을 수 있습니다.
가능하다면 방법 1을 사용하세요 cp -p --attributes-only
. 하지만 먼저 GNU coreutils(즉, 내장되지 않은 Linux 또는 충분히 Linux와 유사한 환경)가 필요합니다. cp
하나도 없으면 이 --attributes-only
옵션을 무시하십시오. 작동하지만 데이터도 복사됩니다.
tmp=$(mktemp)
cp -p --attributes-only "$original" "$tmp"
modifyfile "$original" "$tmp"
mv -f "$tmp" "$original"
예를 들어 파일에 대한 쓰기 액세스 권한이 있지만 파일을 소유하지 않고 소유자를 유지하려는 경우와 같이 기존 파일의 속성을 복사할 수 없는 경우 방법 2만 사용할 수 있습니다. 데이터 손실 위험을 최소화하려면:
- 파일 불완전성에 대한 창을 가능한 한 작게 유지하십시오. 데이터는 먼저 임시 파일에 준비된 다음 해당 위치에 복사됩니다.
- 오래된 파일을 백업하는 것부터 시작하세요.
tmp=$(mktemp)
backup="${original}~"
modifyfile "$original" "$tmp"
cp -p "$original" "$backup"
cp -f "$tmp" "$original"
답변3
첫 번째 답변에 대해 논의한 후 저는 다른 답변을 생각해 냈습니다.
TMP="$(mktemp "$original".XXXXXXXXXX)"
modifyfile "$original" "$TMP"
chmod --reference="$original" "$TMP"
chown --reference="$original" "$TMP"
mv -f "$TMP" "$original"
논평:
- 임시 파일 이
$original
.mktemp
/tmp
$original
/tmp
mktemp
결과에 공백이 포함되어 있으면 이제 따옴표가 붙습니다.- ``대신에 ``를 사용하는
$()
이유는 그것이 더 깨끗하다고 생각하기 때문입니다. ch{mod,own} --reference
$original
에 권한을 전송하는 데 사용됩니다$TMP
. 어떤 메타데이터를 전송할 수 있고 전송해야 하는지에 대한 다른 아이디어가 있는 사람이 있으면 내 게시물을 편집하여 추가하세요.- 아, 그리고 Giles가 지적했듯이 루트 액세스가 필요합니다. 글쎄, 이제 글을 썼으니 넘겨주지 않겠습니다 :P