Linux(WSL2)のユーザー名を変更する

# はじめに

Linux(やWindows等のOS)は、~~よほど特殊な使い方をしない限り~~初めにユーザーを登録し、そのユーザーとしてログインして使用します。
しかし、Typo等で**誤ったユーザー名で作成したものを修正**したい場合や、**後からユーザー名を変更したい**という場合があります。
そのような場合のユーザ名変更方法の覚書です。

## 実行環境

今回は次のような環境で説明します。

- WSL2による仮想環境
- Ubuntu 20.04.2 LTS

基本的には、Linuxであれば他のOSであっても同様の方法で問題ないとは思います。
但し、**既存の他の管理者ユーザー(rootユーザー等)としてログインできる**かによって途中の手順が増えたり減ったりするのでその点だけご確認ください。
(SSHで接続するような場合はrootユーザーでのログインを禁止していることが多いので…)

また、rootユーザーとしてログインするかどうかに関わらず、**管理者権限を有していることが前提**です。
管理者権限がない場合はこの方法を使用できないのでご注意ください。
(変更対象のユーザーが管理者権限を有している必要はありません)

なお、本記事では~~コードクオートの装飾の関係上、~~プロンプトが`$`で`sudo`からコマンドを入力していますが、rootユーザーであればそもそも管理者権限としてプロンプトが`#`となっているので`sudo`は省略してください。

# 忙しい人のために

結論だけ書きます。
root等、変更対象以外のユーザーで次のようにコマンドを入力すれば変更可能です。

```bash
$ sudo usermod -l <変更後ユーザー名> -d /home/<変更後ユーザー名> -m <変更前ユーザー名>
$ sudo groupmod -n <変更後ユーザー名> <変更前ユーザー名>
```

# 手順

大まかな流れは以下の通りです。


1. 変更対象のユーザーで起動したプロセスを全て終了する
2. 変更対象**以外**の管理者ユーザーでログインする
3. `usermod`コマンドでユーザー名とホームディレクトリを変更する
4. `groupmod`コマンドで当該ユーザーのプライマリーグループの名称も変更する

なお、変更対象**以外**のユーザーを用いるのは、`usermod`コマンドによるユーザー名の変更の際に**そのユーザーがログインしていてはならない**[^exec-process]ためです。
[^exec-process]: 厳密には、**そのユーザーで実行中のプロセスが存在してはならない**

今回は例としてユーザー名`hoge`を`fuga`に変更します。

## プロセスの終了

次のようにコマンドを入力を入力することで、当該ユーザーで実行中のプロセスを確認することができます。
実行結果に、`bash`等の現在使用しているターミナルや`ps`以外が含まれていないことを確認してください。

```bash
hoge$ ps ux
```

(実行例)

```
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
hoge       202  0.0  0.0  10052  5128 pts/0    Ss   02:25   0:00 -bash
hoge       218  0.0  0.0  10616  3248 pts/0    R+   02:25   0:00 ps ux
```

なお、筆者の環境では、`./fsnotifier-wsl`や`docker serve`などが実行中となっていました。
これらは、ホストマシンであるWindows側で起動している、JetBrains製IDEやDocker Desktopによるものです。
従って、**ホストマシン側のプロセスを終了**する必要がある場合もあります。

~~ぶっちゃけホストマシンごと再起動した直後にやったほうが賢いとは思います。~~

## 管理者ユーザーの作成

rootユーザー等、**変更対象以外の管理者ユーザー**としてログイン可能な場合は、この手順を飛ばしてください。
WSL2環境でホストマシンから直接操作する場合はrootログインできるハズ…

次のようにコマンドを入力し、**変更対象以外の管理者ユーザー**を作成します。
ここではこのユーザーを`tmpadmin`とします。
(`admin`というグループが既存な場合が多いので…)
なお、このユーザーに対してホームディレクトリを作成したくない場合は`-m`を`-M`に置き換えてください。

```bash
hoge$ sudo useradd -m -s /bin/bash tmpadmin
```

また、rootログインできない環境ならば十中八九パスワードが必要なので、次のように`tmpadmin`にパスワードを設定します。
コマンド入力後に対話式でパスワードを設定する流れです。

```bash
hoge$ sudo passwd tmpadmin
New password:
Retype new password:
```

変更対象のユーザーでログインしたままではユーザー名が変更できないので、一旦ログアウトします。

## 管理者ユーザーとしてログイン

WSL2であれば、コマンドプロンプトやPowerShell等で次のようにコマンドを入力することで、管理者ユーザー(root)でログインできます。

```powershell
> wsl -u root
```

WSL2以外の環境であれば、SSHや実機のコンソール等で、rootユーザーか先程作成した管理者ユーザーとしてログインしてください。

```powershell
> ssh tmpadmin@example.com
```

## ユーザー名の変更

ユーザー名の変更には`usermod`コマンドを使用します。

`usermod`コマンドの基本的な記法は次のようなものです。

```bash
$ sudo usermod [オプション] <対象ユーザー名>
```

このオプションにて変更したい内容等を指定します。

今回は、ユーザー名を変更したいので、`-l`(`--login`)オプションを用いて、変更後のユーザー名を指定します。
次のようなコマンドとなります。
(これはまだ入力しないでください)

```bash
tmpadmin$ sudo usermod -l fuga hoge
```

また、ユーザー名はホームディレクトリの名称にも用いられているので、ホームディレクトリも変更します。
`-d`(`--home`)オプションで変更後のディレクトリを指定します。
また、変更後のディレクトリに現在のホームディレクトリの内容を引き継ぎたいので、`-m`(`--move-home`)オプションを付加します。
よって、ディレクトリの変更(引き継ぎ)は次のようなコマンドとなります。
なお、ホームディレクトリの場所を変更している場合は`/home`の部分を置き換えて適宜対応してください。
(これもまだ入力しないでください)

```bash
tmpadmin$ sudo usermod -d /home/fuga -m hoge
```

よって、今回ユーザー名`hoge`を`fuga`に変更するために、上記2つのオプションを組み合わせた次のようなコマンドを入力することになります。
(これを入力してください)

```bash
tmpadmin$ sudo usermod -l fuga -d /home/fuga -m hoge
```

## グループ名の変更

通常、ユーザーにはプライマリーグループとして、ユーザー名と同名のグループが割り当てられています。
このグループについても名称を変更します。

グループ名の変更には`groupmod`コマンドを使用します。

`groupmod`コマンドの基本的な記法は次のようなものです。

```bash
$ sudo usermod [オプション] <対象グループ名>
```

`usermod`のときと同様に、このオプションにて変更したい内容等を指定します。

今回は、グループ名を変更したいので、`-n`(`--new-name`)オプションを用いて、変更後のグループ名を指定します。
今回はグループ名`hoge`を`fuga`に変更する(基本的にはユーザー名と同名なので)ので、次のようなコマンドを入力することになります。

```bash
tmpadmin$ sudo groupmod -n fuga hoge
```

## 確認

ユーザー一覧は`/etc/passwd`で、グループ一覧は`/etc/group`で確認することができます。
恐らくファイルの末尾付近に当該ユーザーがあると思うので、変更前の名称が残っていないか、変更後の名称が記載されているかを確認してください。
また、`/home/`配下のディレクトリ一覧も確認し、変更前の名称のディレクトリが残っていないか、変更後の名称のディレクトリが存在するかも確認してください。

```bash
$ sudo less /etc/passwd
$ sudo less /etc/group
$ ls -al /home
```

なお、ファイルが長くて読めないという場合等は、`grep`コマンドと組み合わせて以下のように調べることも可能です。

```bash
$ sudo cat /etc/passwd | grep hoge
$ sudo cat /etc/passwd | grep fuga
$ sudo cat /etc/group | grep hoge
$ sudo cat /etc/group | grep fuga
$ ls -al /home | grep hoge
$ ls -al /home | grep fuga
```

## 管理者ユーザーの削除

今回管理者ユーザーを作成した場合の手順です。
rootユーザー等既存のユーザーを使用した場合は読み飛ばしてください。
(と言っても、この記事にこれより後はありませんが…)

今まで作業していた`tmpadmin`からログアウトして、他の管理者ユーザー(今回名称を変更したユーザー等)でログインし直してください。

ユーザーの削除には`userdel`コマンドを使用します。
ここで、ユーザーディレクトリ等も削除するために、`-r`オプションを付加します。
よって、`tmpadmin`というユーザーを削除するためには、次のようなコマンドを入力することになります。

```bash
fuga$ sudo userdel -r tmpadmin
```

このとき、`userdel: tmp mail spool (/var/mail/tmp) not found`等のエラーが表示されるかと思いますが、無視して問題ありません。

先程と同様に、`tmpadmin`ユーザーが残っていないか確認してください。

```bash
tmpadmin$ sudo cat /etc/passwd | grep tmpadmin
tmpadmin$ sudo cat /etc/group | grep tmpadmin
tmpadmin$ ls -al /home | grep tmpadmin
```

# 参考

[【 usermod 】コマンド――ユーザーアカウントの情報を変更する：Linux基本コマンドTips（73） - ＠IT](https://www.atmarkit.co.jp/ait/articles/1612/14/news022.html)
[【 groupmod 】コマンド――グループIDや名前を変更する：Linux基本コマンドTips（260） - ＠IT](https://www.atmarkit.co.jp/ait/articles/1811/22/news031.html)
[【 useradd 】コマンド――新規ユーザーを作成する：Linux基本コマンドTips（255） - ＠IT](https://www.atmarkit.co.jp/ait/articles/1811/02/news035.html)
[【 userdel 】コマンド――ユーザーを削除する：Linux基本コマンドTips（257） - ＠IT](https://www.atmarkit.co.jp/ait/articles/1811/09/news031.html)