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にその権限がない場合でもrootシェルを取得できます。これを「権利上昇」といい、悪いのです。

この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

エディターは root 以外のユーザーとして実行されるため、特権の昇格にはエディターを使用できません。

非常に許容可能な 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にもう一度感謝します。

関連情報