えいあーるれいの技術日記

ROS2やM5 Stack、Ubuntuについて書いています

sudoで実行するけど、一般ユーザ名を確実に$USERにしたい場合の書き方(Shell)

Qiitaに投稿するかどうか迷ったけど、こちらに投稿します。

自作スクリプトを作る時に、sudoが必要なコマンドと使ってはいけないコマンドがあると思います。sudoが必要なコマンドといえば、aptコマンドや/local/optなどの管理者権限が無いと読み書きできないコマンドなどがあります。

手動でシェルスクリプトを起動するなら、こうやってプログラムを記述することができます。

#!/bin/bash

# 通常ユーザで実行
commandA

# superuserで実行
sudo commandB

# USERは?
echo $USER

echo $HOME

$USER$HOMEはsuperuserではないため、実行結果は一般ユーザ(ログイン時の名前)で出力されます。もちろん実行時にはパスワードが必要です。

さて、自動でスクリプトを管理者権限で実行したい場合があります。例えば、mountコマンドでusbマウントする時とか…

systemdだったら、root権限上でこのように記述したら良いかもしれません。

# 通常ユーザで実行
commandA

# superuserで実行
commandB

#USERは ?
echo $USER

echo $HOME

この場合、全てのコマンドはsuperuserで実行されます。そのため、echo $USERrootとなります。しかし、これでは困る場合があります。例えば、ローカルにファイルをコピーするときです。

不特定多数の人がインストールすることを考えれば、$USER$HOMEを使いたいところですが、すべてrootになってしまうため、うまく行きません。

もちろんsudoersなどで実行できるコマンドを増やしても良いですけど、そんな設定に手間かけるのもイヤだし、アンインストールを忘れてグループがそのままになるのもつらいのでできる限り使いたくありません…

そこで、ダウンロードしたファイルのパスを利用した一般ユーザ抽出スクリプトを作ってみました。他にもっと(環境構築的に)簡単な方法があれば教えてください(._.)

管理者権限で実行するときの一般ユーザ名抽出プログラムを示します。区別のために、$LOCAL_USERを出力とします。

なお、これが記述されたファイルが/home/<username>以下にないと詰みます。そんなことしないと思うけど…

#!/bin/sh
echo $USER

## Script dir
SCRIPT_DIR=$(cd $(dirname $0); pwd)
echo "Step0: $SCRIPT_DIR"

# Step1
_USER=${SCRIPT_DIR##*home/}
echo "Step1: $_USER"

# Step2
LOCAL_USER=${_USER%%/*}
echo "Step2: $LOCAL_USER"

実行結果です。

1回目は管理者権限、2回目は一般ユーザで実行しています。

f:id:Ray_ar:20210806224513p:plain

Step0は、おなじみのファイル場所のディレクトリを抽出する行です。

Step1とStep2は、「一番最初の/home/を切り取る→<username>//以下の文字列を削除する」というプロセスを実行して一般ユーザ名を切り取ります。

そして、そのStep2の結果がそのまま一般ユーザ名として使えます。USER=$LOCAL_USERとしてもいいと思います。


シェルスクリプトの書き方はいろいろあるのでどれが正しいのかイマイチ分かっていない部分も多いですが、気づいたところを書いて「こんな書き方あるよ❗」みたいな議論があると勉強になっていいなーーと思います。(arpコマンドとか知らなかったし…)

他の人から見たら「え❓結構回り道じゃない❓」と思うような記法も気づいたら遠慮なく書いていこうと思っているので、ぜひ目を通していただけるとありがたいです。

↓コピペ用

SCRIPT_DIR=$(cd $(dirname $0); pwd)
_USER=${SCRIPT_DIR##*home/}
USER=${_USER%%/*}