web-dev-qa-db-ja.com

stdoutを書き込み権限のないファイルにリダイレクトする

書き込み権限がないファイルを変更しようとすると、エラーが発生します。

> touch /tmp/foo && Sudo chown root /tmp/foo
> echo test > /tmp/foo
zsh: permission denied: /tmp/foo

Rootとしてコマンドを実行するため、sudoingは役に立ちませんが、シェルはstdoutのリダイレクトを処理し、とにかくファイルを開きます。

> Sudo echo test > /tmp/foo
zsh: permission denied: /tmp/foo

Rootとしてシェルを開き、ファイルをそのように操作する以外に、書き込み権限のないファイルにstdoutをリダイレクトする簡単な方法はありますか?

> Sudo su
# echo test > /tmp/foo
115
Michael Mrozek

はい、teeを使用します。そう echo test > /tmp/foo

echo test | Sudo tee /tmp/foo

>>

echo test | Sudo tee -a /tmp/foo
119
Gert

ファイルの内容をechoの出力に置き換えるには(>シェルリダイレクト演算子のように)。

echo test | Sudo dd of=/tmp/foo

1<> Bourne Shell演算子のように)切り捨てずにファイルに書き込むには(最初はseekを使用して異なるオフセットで出力できます):

echo test | Sudo dd of=/tmp/foo conv=notrunc

GNU ddを使用して、ファイルに追加するには(>>など):

echo test | Sudo dd of=/tmp/foo oflag=append conv=notrunc

POSIXシェルのconv=exclのように既存のファイルを破壊しないようにするためにはGNU ddset -o noclobberも参照し、反対の場合はconv=nocreatも参照してください(更新のみ)既存のファイル)。

27
Chris Jepeway

teeがおそらく最良の選択ですが、状況によっては次のようなもので十分かもしれません。

Sudo sh -c 'echo test > /tmp/foo'
14
phunehehe

私は同意しますが、その| Sudo teeは標準的な方法であり、時にはsed(GNU sedと仮定)が機能する場合があります:

cat sudotest 
line 1

Sudo sed -i '1iitest' sudotest && cat sudotest 
itest
line 1

Sudo sed -i '$aatest' sudotest && cat sudotest 
itest
line 1
atest

-iは、ファイルを適切に変更します。 1iは、1行目の前にinsertを意味します。$aは、最後の行の後にappendを意味します。

または、xclipboardにコピーします。

somecommand | xclip
Sudo gedit sudotest
move cursor to desired place, click middle mouse button to insert, save
5
user unknown

私は同様の問題について私の考えの裏を駆け回り、次の解決策を考え出しました:

  • Sudo uncatここでuncatは、標準入力を読み取ってコマンドラインで指定されたファイルに書き込むプログラムですが、uncatはまだ書いていません。

  • sudocatsudoeditのバリアントです。まだ記述していませんが、クリーナーSudo catまたはSudo uncat

  • または、シェルスクリプトであるEDITORでsudoeditを使用するこの小さなトリック

    #!/bin/sh
    # uncat
    cat > "$1"
    

    どちらかとして呼び出すことができます|Sudo ./uncat fileまたは| EDITOR=./uncat sudoeditしかし、これには興味深い副作用があります。

2
hildred

Moreutilsパッケージのスポンジを使用します。 stdoutに書き込まないという利点があります。

echo test | Sudo sponge /tmp/foo

-aオプションを使用して、ファイルを上書きするのではなく、ファイルに追加します。

1

エラーは、シェルが実行する順序から発生します。

リダイレクトはシェルがSudoを実行する前に処理されるため、現在作業しているユーザーの権限で実行されます。リダイレクトのターゲットを作成/切り捨てる書き込み権限がないため、permission deniedシェルからのエラー。

解決策は、出力ファイルがSudoによって指定されたIDで作成されることを保証することです。 tee

$ generate_output | Sudo tee target_file
0
Kusalananda