Sudoedit Vim 종료하지 않고 강제 쓰기(업데이트)

Sudoedit Vim 종료하지 않고 강제 쓰기(업데이트)

저는 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과 같은 쉘 이스케이프 기능이 있어 :shellsudo에서 해당 권한이 없더라도 루트 쉘을 얻을 수 있습니다. 이것을 "권한 상승"이라고 하며 나쁜 것입니다.

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에게 다시 한 번 감사드립니다.

관련 정보