私は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にその権限がない場合でも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にもう一度感謝します。