スーパーユーザー権限が必要なファイルにcatコマンドでテキストを書き込む。

いまだにChefのようなかっこいいツールが使えない僕は、インフラの設定をシェルスクリプトでつらつらと残していたりします。
設定ファイルの書き換えや作成などが少し面倒で、catコマンドでテキストを吐かせて出力をファイルにリダイレクトさせて書き込みます。

cat << 'EOT' > ./config
Host myserver
  HostName 8.8.8.8
  User katty0324
EOT

こういう感じです。

書き込み権限がないとcatの出力を書き込めない

これは書き込み先のファイルの権限があれば良いのですが、権限がないと書き込めないような場合、少し困ります。

sudo chmod u-w ./config

わざと書き込み権限を除去して同じコマンドを実行します。

$ cat << 'EOT' > ./config
> Host myserver
>   HostName 8.8.8.8
>   User katty0324
> EOT
-bash: ./config: Permission denied

さきほどのコマンドが使えなくなりました。ここまでは理解可能。
スクリーンショット 2013-08-06 19.29.46

sudoしても書き込めない

スーパーユーザー権限があれば良い場合、sudoなどをして編集します。
しかし、この場合、sudoしてもダメです。catコマンドはスーパーユーザーの権限で実行されますが、その出力のリダイレクト先は、元のユーザーの権限に戻ってしまいます。

$ sudo cat << 'EOT' > ./config
> Host myserver
>   HostName 8.8.8.8
>   User katty0324
> EOT
-bash: ./config: Permission denied

リダイレクトまで含めてスーパーユーザー権限で実行

というわけで調べていたら、出てきたのが以下のブログでした。
sudo コマンド実行しても、リダイレクトでファイルに書き込めない.
sudo sh -cの引数にコマンド全体を渡すことで、リダイレクトまで含めてスーパーユーザー権限で実行できます。

sudo sh -c "cat << 'EOT' > ./config
Host myserver
  HostName 8.8.8.8
  User katty0324
EOT"

これは確かに動くんですが、テキスト部分の特殊文字が解決されてしまう場合がありますので、いちいちエスケープをかけてやらなければならなかったりしてとても面倒です。

スーパーユーザー権限のteeコマンドにパイプ

そういうわけで最終的にteeコマンドにパイプで渡して、teeコマンドをスーパーユーザー権限で実行すれば良いというところにたどり着きました。

sudo cat << 'EOT' | sudo tee ./config
Host myserver
  HostName 8.8.8.8
  User katty0324
EOT

というのを調べていたのは半年くらいまえなのですが、そのシェルを「これなんですか」的な感じで言われたので書きました。

コメント

タイトルとURLをコピーしました