6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Sudo を使ってシェルスクリプトを実行するときに、環境変数も引き渡したい

Last updated at Posted at 2019-12-19

プロビジョニングスクリプトを書いています。そのプロビジョニングスクリプトはRootで実行されるのですが、そのスクリプトから、他のユーザとして、別のスクリプトを実行したいというケースがありました。その子スクリプトは、サーバーを起動します。

ところが、そのサーバーの挙動がおかしく、原因は、親スクリプトで設定した環境変数が、子スクリプトに渡っていない様子です。そのサーバーをプロビジョニングしたVMで手動で起動するとすべての環境変数設定が出来て正しく起動しますので、一瞬不思議にみえますが、単純にプロビジョニングスクリプトでの実行時に環境変数がわかっていないのです。

他のユーザとして、シェルを実行する方法

他のユーザとしてシェルの実行はsudoを使います。現在のユーザが、そのユーザに対して権限がなければ、パスワードを求められますが、例えばRootユーザから、他のユーザになる場合は、パスワードは求められません。

$ sudo -u ushio ./child.sh

ところが、この方法では、親スクリプトで設定した環境変数が渡りません。試してみましょう。

parent.sh

# !/bin/bash

export FOO=BAR

sudo -u ushio ./child.sh 

child.sh

# !/bin/bash

# source ~/.bashrc

echo "FOO: "${FOO}

実行結果

sudo su 
[sudo] password for ushio: 
# ./parent.sh 
FOO: 

何も表示されません。ちなみに、source ~/.bashrc の部分を有効にすると、./child.sh: line 3: /root/.bashrc: Permission denied のエラーになります。これは、別のユーザで実行しても、root としてみなされている雰囲気のようです。実際に、env コマンドをchild.shで実行してみると、パスの構成などからみて、ushioユーザの.bashrcは実行されていないようです。これが、envをchild.sh で実行してみた結果ですが、なんとも中途半端な感じになっていて、パスは、Rootのものだけど、環境変数は特にわたっていません。

LANG=C.UTF-8
SUDO_GID=0
DISPLAY=127.0.0.1:0.0
COLORTERM=truecolor
USERNAME=ushio
SUDO_COMMAND=./child.sh
USER=ushio
PWD=/home/ushio/Codes/DevSecOps/volley/playground/environmentvariables
HOME=/root
SUDO_USER=root
SUDO_UID=0
MAIL=/var/mail/ushio
SHELL=/usr/bin/zsh
TERM=xterm-256color
SHLVL=1
LOGNAME=ushio
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin
_=/usr/bin/env

 解決策

とても簡単で、-E オプションを使います。

parent.sh

# !/bin/bash

export FOO=BAR

sudo -u ushio -E ./child.sh 

実行結果

# ./parent.sh 
FOO: BAR

よりより解決策

今回は、-E で解決ですが、--preserve-env=で特定の環境変数も渡せるようですね。

sudo -u ushio --preserve-env=FOO ./child.sh に変更しても結果は同じでうまくいきました。

     -E, --preserve-env
                 Indicates to the security policy that the user wishes to preserve their existing environment vari‐
                 ables.  The security policy may return an error if the user does not have permission to preserve the
                 environment.

     --preserve-env=list
                 Indicates to the security policy that the user wishes to add the comma-separated list of environment
                 variables to those preserved from the user's environment.  The security policy may return an error if
                 the user does not have permission to preserve the environment.

複数のものも試してみましょう。カンマ区切りと書いてあります。

parent.sh

# !/bin/bash

export FOO=BAR
export BUZ=QUUX

sudo -u ushio --preserve-env=FOO,BUZ ./child.sh 

実行結果

# ./parent.sh 
FOO: BAR
BUZ: QUUX
``


# 追記 $HOME 環境変数にご注意

`-E` を追加したところ、スクリプトが思わぬところで失敗しました。`$HOME` 環境変数が、`-E`なしの時はターゲットのユーザとして動作するので例えば `/home/ushio` になるのですが、`/root`になってしまうようです。先ほどのenv
を`--preserve-env=list` でやってみましょう。ああ!なるほど、だから`--preserve-env=list`オプションがあるのか!意図したもののみ入れ替えるわけですね。

```bash
LANG=C.UTF-8
SUDO_GID=0
DISPLAY=127.0.0.1:0.0
COLORTERM=truecolor
USERNAME=ushio
SUDO_COMMAND=./child.sh
USER=ushio
PWD=/home/ushio/Codes/DevSecOps/volley/playground/environmentvariables
HOME=/root
SUDO_USER=root
FOO=BAR
SUDO_UID=0
MAIL=/var/mail/ushio
SHELL=/usr/bin/zsh
TERM=xterm-256color
SHLVL=1
LOGNAME=ushio
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin
_=/usr/bin/env
FOO: BAR
6
4
0

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
6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?