저는 Vim을 사용하여 일부 스크립트를 작성하고 있으며 이제 막 sudoedit
.
문제는 :w
임시 파일에 쓸 때 편집기를 종료하지 않는 한 스크립트 테스트가 발생하지 않는다는 것입니다.
원본 버전으로 강제 업데이트하려면 어떻게 해야 합니까? 아니면 요점을 놓치고 있는 것입니까 sudoedit
?
답변1
sudoedit
자신의 사용자 ID로 실행되는 편집기를 사용하여 파일을 편집할 수 있습니다. 파일을 임시 파일에 복사한 다음 편집자가 쓸 수 있습니다. 편집기가 닫히면 편집된 파일이 다시 복사됩니다.
편집기가 계속 실행되는 동안 변경 사항을 자동으로 다시 쓸 수 있는 기능이 내장되어 있지 않습니다.
그래서 당신은 필요
- 다른 사용자 ID로 편집기 실행(예
sudo vi /file/to/edit
: ) - (별도의) 셸(
sudo cp /tmp/... /file/to/edit
)이나 vim 내에서 수동으로 파일을 복사합니다:!sudo cp % /file/to/edit
. vim에서는 Ctrl+Z를 사용하여 셸을 시작:sh
하거나 vim을 백그라운드에 둔 다음 를 사용하여 다시 시작할 수도 있습니다fg
. - 사용https://stackoverflow.com/questions/2600783/how-does-the-vim-write-with-sudo-trick-work
sudoedit
임시 파일이 변경되면 변경 사항을 다시 기록하는 고유한 버전을 만듭니다 . 이는 일부 스크립팅을 통해 쉽게 가능합니다. Inotify는 변경 사항을 감지하는 데 도움이 될 수 있습니다(예제 참조).Bash 스크립트를 파일에 연결할 수 있나요?)
답변2
sudoedit의 요점을 놓치고 계시는데, 매뉴얼에는 이에 대한 설명이 없으니 걱정하지 마세요.
대부분의 편집자에는 vim과 같은 쉘 이스케이프 기능이 있어 :shell
sudo에서 해당 권한이 없더라도 루트 쉘을 얻을 수 있습니다. 이것을 "권한 상승"이라고 하며 나쁜 것입니다.
이 sudoedit
명령은 다음과 동일합니다.
# cp source-file /tmp/some-temporary-name
$ ${EDITOR} /tmp/some-temporary-name
# cp /tmp/some-temporary-name source-file
# rm /tmp/some-temporary-name
편집기는 루트가 아닌 사용자로 실행되므로 권한 상승을 위해 편집기를 사용할 수 없습니다.
매우 허용적인 sudo 권한이 있는 경우(배포판에 따라 단일 사용자 컴퓨터에서 흔히 발생함) 다음을 수행할 수 있습니다.
$ sudo vim source-file
원하는 행동을 취하십시오.
답변3
sudoedit
임시 파일에 대한 쓰기 inotifywait
를 수신하고 원본 파일을 업데이트하는 것을 직접 만들었습니다 . 처럼 여전히 $EDITOR
스크립트를 호출한 사용자로 실행됩니다 sudoedit
.
#!/bin/bash
tmp="/tmp/$(mktemp $(basename $1).XXXXXXXXXXXX)"
sudo cat "$1" > "$tmp"
inotifywait -m "$tmp" -e create -e moved_to -e close_write 2>/dev/null > \
>(sudo sh -c "while read path action file; do cp '$tmp' '$1'; done") &
pid=$!
sh -c "$EDITOR $tmp"
kill $pid
/usr/bin/rm "$tmp"
답변4
현재 제가 사용하고 있는 버전입니다. 이전 것은 나에게 깨졌습니다.
#!/bin/bash
abs_filepath() {
echo "$(cd "$(dirname "$1")" && pwd)/$(basename "$1")"
}
su_cat() {
sudo sh -c 'cat "$1" > "$2"' -- "$1" "$2"
}
file_name="${1##*/}"
file_path="$(abs_filepath "$1")"
extension=$([[ "$file_name" = ?*.* ]] && printf ".${file_name##*.}" || printf '')
tmp="$(mktemp /var/tmp/$file_name.XXXXXXXXXXXX$extension)"
[ -f "$file_path" ] && sudo cat "$file_path" > "$tmp"
(
while true; do
# dummy variable to wait for an event
_=$(inotifywait -q -e create -e moved_to -e close_write "$tmp")
if [ -f "$tmp" ]; then
su_cat "$tmp" "$file_path"
fi
done
) &
listener_pid=$!
nvim "$tmp"
kill $listener_pid
# wait for the process to finish. Simple `wait` doesn't work here
while $(kill -0 $listener_pid 2>/dev/null); do
sleep 0\.5
done
su_cat "$tmp" "$file_path"
rm "$tmp"
몇 가지 버그를 수정했습니다. 주요 문제는 vim/nvim 편집기입니다. 파일을 복사하고 편집한 다음 다시 복사하는 메커니즘이 있습니다. 그래서 실제 TMP 파일이 삭제되었기 때문에 손상이 된 것입니다.
하지만 원본 스크립트를 제공해 주신 Marcel과 Processor에게 다시 한 번 감사드립니다.