LoginSignup
28
25

More than 5 years have passed since last update.

シェルスクリプトで所有者がrootのファイルを編集する3つの方法

Last updated at Posted at 2016-06-06

vagrantをプロビジョニングするときに、自動で/etc/hostsに追記(編集)できたら、きっと楽になるはず!!!
vagrantはrootでプロビジョニングが可能ですが、全ての作業をrootで作業したくない・・・。
というわけで、/etc/hostsを例に、所有者がrootのファイルを編集する方法を3つ紹介します。

検証した環境

  • Mac
Macの開発環境
$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.11.5
  • CentOS(vagrant)
CentOSの開発環境
$ cat /etc/redhat-release
CentOS Linux release 7.2.1511 (Core)

手動で/etc/hostsを書き換える時に、sudoが必要な理由

手動で/etc/hostsを書き換える場合には、先頭にsudoを付ける必要があります。

手動で/etc/hostsの編集(mac&centos)
$ sudo vim /etc/hosts

/etc/hostsの所有者を確認すると、rootとなっています。

/etc/hostsの所有者(mac)
$ ls -la /etc/hosts
-rw-r--r--  1 root  wheel  303  5 30 18:23 /etc/hosts

そのため、ファイルの編集にはroot権限が必要となります。
sudoコマンドでは、ユーザの指定を省略すると、rootユーザ(スーパーユーザ)による実行とみなされます。

シェルスクリプトで書き換える方法

その1:実行時にsudoをつける

/tmp配下に適当なシェルスクリプトを作成します。

シェルスクリプトを作成
$ cd /tmp
$ vim test.sh
シェルスクリプトの中身
#!/bin/sh
echo 127.0.0.1 example.com >> /etc/hosts

このスクリプトは、/etc/hosts127.0.0.1 example.comを追記します。
それでは、作成したシェルスクリプトを実行します。

シェルスクリプトの実行
$ sh test.sh
test.sh: line 2: /etc/hosts: Permission denied

しかし、Permission denied(権限がない)と怒られます。
先頭にsudoをつけて実行すると、問題なく成功します。

rootユーザでシェルスクリプトの実行と結果
$ sudo sh test.sh
Password:                   ← パスワード入力

# 実行結果
$ cat /etc/hosts | grep example.com
127.0.0.1 example.com

その2:シェルスクリプト内で実行するコマンドでrootユーザになる(1)

その1のように、sudoを付けてシェルスクリプトを実行できる時は、これで問題ありません。
しかし、vagrantのプロビジョニングのように、ある特定の場合のみrootで実行したい場合、以下の方法が有効です。

シェルスクリプトを編集
$ cd /tmp
$ vim test.sh
シェルスクリプトを編集した結果
#!/bin/sh
sudo -- sh -c "echo '127.0.0.1 example.com' >> /etc/hosts"

sudo -- shは、rootユーザでシェルスクリプトを実行するコマンドとなります。また、-cオプションを指定することで、文字列(今回はechoを含む文字列)がコマンドとして読み込まれます。

シェルスクリプトの実行
$ sh test.sh
Password:                   ← パスワード入力
 
# 実行結果
$ cat /etc/hosts | grep example.com
127.0.0.1 example.com
127.0.0.1 example.com             ← 追記されている

その3:シェルスクリプト内で実行するコマンドでrootユーザになる(2)

コメントしていただいた方法を追記します。
この方法もvagrantのプロビジョニングのように、ある特定の場合のみrootで実行したい場合、以下の方法が有効です。

シェルスクリプトを編集
$ cd /tmp
$ vim test.sh
シェルスクリプトを編集した結果
#!/bin/sh
sudo sh -c "echo '127.0.0.1 example.com' >> /etc/hosts"

sudo shは、その2で紹介した方法の短縮形となります。sudoコマンドでは、ユーザの指定を省略すると、rootユーザによる実行とみなされるため、この方法でも追記が可能となります。

シェルスクリプトの実行
$ sh test.sh
Password:                   ← パスワード入力
 
# 実行結果
$ cat /etc/hosts | grep example.com
127.0.0.1 example.com
127.0.0.1 example.com             
127.0.0.1 example.com             ← 追記されている

まとめ

今回は、所有者がrootユーザのファイル例として/etc/hostsを紹介しました。
他のファイルにもこの方法は有効です。
また、今回は追記する方法を紹介しましたが、もちろんsedや他のコマンドも使うことができます。

#!/bin/sh
sudo -- sh -c "sed 's/example/test/g' /etc/hosts"

vagrantのプロビジョンの際には、パスワードを求められないのでroot権限が必要なファイルのプロビジョニングには有効です。
ぜひ、使ってみてください〜〜〜!

28
25
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
28
25