sudoでnanoを起動するのを忘れたときにnanoからrootとして保存できますか?

sudoでnanoを起動するのを忘れたときにnanoからrootとして保存できますか?

何度もファイルを編集してnano保存しようとしましたが、rootとして実行するのを忘れてしまったため、権限エラーが発生しました。sudoファイルを再度開いて編集しなくてもエディタ内でルートになる簡単な方法はありますか?

答え1

いいえ、実行中のプログラムが起動したときに持っていない権限を付与することはできません。これは「権限エスカレーション」というセキュリティホールです。

次の2つのことができます。

  1. /tmpまたは他の場所に一時ファイルを保存し、エディタを閉じて一時ファイルの内容を編集中のファイルにダンプします。sudo cp $TMPFILE $FILE。この方法mvはファイルの所有権と権限が変更される可能性があるため、お勧めできません。ファイルプレースホルダー自体ではなく、ファイルの内容を変更するだけです。
  2. Ctrl+を使用してエディタをバックグラウンドにし、ファイルの所有z権または権限を変更して書き込むことができるようにし、を使用してエディタfgに戻って保存します。権限を変更することを忘れないでください!

一部の編集者は、実際には別の権限で新しいプロセスを開始し、保存するためにそのプロセスにデータを渡すことでこれを行うことができます。例を見るこの関連質問パイプを処理するためのファイルバッファの書き込みを可能にする高度なエディタの他のソリューション用です。 Nanoには、新しいプロセスを開始したり、データを別のプロセスに渡したりする機能がないため、除外されます。

答え2

私が試してみましたが、nano最も驚くべきことは、ファイルの編集を開始したときにファイルが読み取り専用であるという警告さえ表示しないことです。 (アップデート:nano 2.2では警告が発生しないようです。)

これはこれを行う(デフォルト)スクリプトです。

ファイルを編集できることを確認し、そうでない場合は「nano」をrootとして実行します。

/usr/local/bin/editroot(または~/空/編集ルート)

sudo=                       # empty is false, non-empty is true
editor=nano                 # XXX check $EDITOR and $VISUAL

if test -e "$1" && test ! -w "$1"; then
    if test -t 0 && test -t 2; then
        printf "%s is not writable.  Edit with sudo? [y/n] " "$1" 1>&2
        read -n 1
        case $REPLY in
        y|Y)
            sudo=true
            ;;
        n|N)
            sudo=
            ;;
        *)
            printf "\nExpected y or n.  Exiting.\n" 1>&2
            exit 1
            ;;
        esac
    else
        printf "%s is not writable.  Fix the permissions or run \"view\" instead." "$1" 1>&2
        exit 1
    fi
fi

${sudo:+sudo} "$editor" "$1"

view変更がないことがわかっている場合は、プロンプトを避けるためにコマンドを呼び出しました。

/usr/local/bin/view(または~/bin/views)

editor=nano
readonlyflag=-v

"$editor" $readonlyflag "$1"

Vi/Vimの一部というプログラムがすでにあるので、viewより良い名前を提案してください。
(しかし、私はこのプログラムを完全に実装するとViがview重複すると思います。)


完全版

答え3

nanoバージョン2.9.8(2018)には、外部コマンドでテキストをフィルタリングする機能が追加されました。

外部コマンドでバッファ内のテキストをフィルタリングすると、アクセス権がある場合はsudo tee some/path/fileテキストがルートとして保存されます。some/path/filesudo

エディタでこれを行うには、^R^X+を押して次のようにCtrl+R入力Ctrl+Xします。

|sudo tee some/path/file

これはsome/path/filerootとしてオーバーライドされます。

現在の編集セッションを中断してファイルを再開する方が安全です。sudo nano some/path/fileなぜなら、フルパス名を正しく入力しなくても、シェルのファイル名オートコンプリート機能を使用できるからです。

答え4

短い答え(詳しくはお読みください):

  1. エディタでファイルを開く
  2. 別の端末/bashセッションに移動
  3. 元のファイルのバックアップ
  4. 走るf=forgotsudo.oops; cd ~; [ -e $f ] || mkfifo $f; sudo sh -c "cat $f >> [filename]"; rm $f
  5. エディタでファイルを保存すると、~/forgotsudo.oops以下のように元のファイルにコンテキストが追加されます。sudo

このプロセスは複雑に見えますが、ほぼ一文で処理できます。

これを頻繁に実行する場合は、再利用のためにスクリプトを作成できます。

詳しくは:

私が新しい解決策だと思うことを初めて試しているので、経験のある人がこれを確認できることを願っています。以前に言及したことがないので、実際に機能するとは思わなかった。何らかの理由で私が考えていなかった内容がひどいアイデアであることが判明したら、削除します。

スクリプト()に含めることで、より堅牢にすることができるようですforgotsudo

fifoアプローチの利点は、エディタが外部コマンドを介してフィルタリングできるかどうかにかかわらず、ほとんどすべてのエディタで機能することです。

詳細な説明:

ファイル(たとえば/etc/abcdef.conf)を保存しようとしましたが、ファイルを保存することを忘れたことがわかったら、sudoBashで別の端末(またはtmuxウィンドウなど)を開きます。

sudo cp /etc/abcdef.conf /etc/abcdef.conf.bak # back up the original file
cd ~ # or somewhere with write permissions
mkfifo forgotsudo.oops
sudo cat forgotsudo.oops >> /etc/abcdef.conf ; rm forgotsudo.oops

たとえfifo追加~/forgottosudo.oops実際のファイルとしてエディタに切り替え、エディタの一般的な「保存」技術を使用してバッファを保存します。たとえば、

  • ビームでは:w! ~/forgotsudo.oops
  • NanoでCtrl+Oにファイル名を変更し、~/forgotsudo.oopsYを選択して別のファイル名で保存し、もう一度Yを選択して「上書き」を確認します。

この場合、変更されたバッファは次のようになります。追加元のファイルに。その後、エディタを終了してファイルを再編集して、sudo「重複」ソースファイルを削除できます。もちろん、これは、重複したコンテンツが原因で「ブロックされた」一部のプロセスでファイルを使用しないことを前提としています。

「間違ったデータ」に敏感なファイルの場合は、もちろん単一のファイルを使用して>既存のファイルを新しいコンテンツで上書きすることもできます。ただしsudo cat ...、一旦実行されると元のファイル内容は破棄されますのでご注意ください。何らかの理由でエディタでバッファが失われると、ファイルは破壊または空になります。必ずバックアップしてください。

注:上書きしたり追加したりしても、元のファイル権限は保存後に変更されません。

関連情報