sudoでリダイレクトするとエラーが出た時の解決法

書き込みにroot権限が必要なファイルに、リダイレクトで書き込みたいことがありますよね。でも、「sudo」を使って以下のように実行しても、期待に反してエラーが出てしまいます。

$ sudo echo 'test' > /root/test.txt
bash: /root/test.txt: 許可がありません

これは、echoコマンドはルート権限で動いているものの、リダイレクト処理はsudoを実行した一般ユーザーの権限で行われているためです。上の例だと、/root/test.txtを作成したり書き込んだりできるのはrootだけなので、エラーが出たというわけです。

解決策1・teeを使う

この問題は、「tee」を使うことで簡単に回避できます。teeは、標準入力を標準出力(通常は端末画面)とファイルの両方に出力するコマンドです。「コマンド | sudo tee ファイル」のように、リダイレクトする代わりに、sudoで実行したteeにパイプで渡します。以下は実行例です。

$ echo 'test' | sudo tee /root/test.txt
test

画面出力が不要なら、「> /dev/null」をつけて実行します。

$ echo 'test' | sudo tee /root/test.txt > /dev/null

>>」を使ってリダイレクトした時のように、ファイルに追記するならteeに「-a」オプションをつけます。

$ echo 'test' | sudo tee -a /root/test.txt > /dev/null

この例では「echo」は一般ユーザーとして実行しましたが、「sudo」をつけて実行したコマンドの出力を「sudo tee」にパイプで送ることも、もちろんできます。

解決策2・sudoで実行したシェルにコマンド文を渡す

リダイレクトを含むコマンド文をsudoで実行したshに渡す方法もあります。以下のように実行します。

sudo sh -c "echo 'test' > /root/test.txt"

この方法なら、rootで動作するシェルでリダイレクトも実行されます。この方法だと、「echo 'test'」もルート権限で実行されています。