TL;DR ... ホームディレクトリはsudoで実行したかにかかわらず, getent passwd ${SUDO_USER:-$USER} | cut -d: -f6 で得られる.

問題と解決策

bash において, ログインユーザ名やホームディレクトリは環境変数から取得できる.

$ echo "$USER"
yammerjp
$ echo "$HOME"
/home/yammerjp

しかしながら, sudo で実行される場合, これらは root のものとして扱われてしまう.

$ echo 'echo "$USER"' | sudo bash
root
$ echo 'echo "$HOME"' | sudo bash
/root

こうなると, sudo のシェルスクリプトの中で, 実行ユーザの名前やホームディレクトリを知りたいときに困る.

これを解決するには, 環境変数 $SUDO_USER を用いればよい.

$ echo 'echo "$SUDO_USER"' | bash

$ echo 'echo "$SUDO_USER"' | sudo bash
yammerjp

さらに特定のユーザ名のホームディレクトリもこれを使って求められる.

$ cat username.sh
#!/bin/bash
echo ${SUDO_USER:-$USER}
getent passwd ${SUDO_USER:-$USER} | cut -d: -f6

$ bash username.sh
yammerjp
/home/yammerjp
$ sudo bash username.sh
yammerjp
/home/yammerjp

何故 getent passwd ${SUDO_USER:-$USER} | cut -d: -f6 で得られるのか

${SUDO_USER:-$USER}

$SUDO_USER には, sudo実行時には元のユーザ名が入っており, 非sudo時には空になる. ${SUDO_USER:-$USER} を用いると, $SUDO_USER の値もしくはこれが空なら $USER の値を表す.

getent

getent passwd は, システムの認証方法にかかわらず (例えばLDAPを使っていたとしても) ユーザの認証情報 を /etc/passwd に記述される形式で取得できる.

/etc/passwd の各行は : (コロン) 区切りでユーザ名やホームディレクトリやログインシェルを含むので, 適切に cut してあげると ホームディレクトリが得られる.

実験用のシェルスクリプト

#!/bin/bash

echo -e "\n$ whoami"
whoami

echo -e "\n$ echo \$HOME"
echo $HOME

echo -e "\n$ echo \$USER"
echo $USER

echo -e "\n$ echo \$USERNAME"
echo $USERNAME

echo -e "\n$ getent passwd \$USER | cut -d: -f6"
getent passwd $USER | cut -d: -f6

echo -e "\n$ echo \$SUDO_USER"
echo $SUDO_USER

echo -e "\n$ echo \${SUDO_USER:-\$USER}"
echo ${SUDO_USER:-$USER}

echo -e "\n$ getent passwd \${SUDO_USER:-\$USER} | cut -d: -f6"
getent passwd ${SUDO_USER:-$USER} | cut -d: -f6