create_students.py(ユーザー作成 + フォルダ作成)
create_students.py は、受講生の Linux ユーザーと
/var/www/html/<folder> のフォルダを
CSV から一括作成する自動化スクリプトです。
本スクリプトは、本サイト管理者と AI(Microsoft Copilot)との共同制作教材として作成されました。 初心者でも扱えるように、GUI の CSV 選択だけで実行できるよう設計されています。
最終更新:
目次
スクリプトの配置方法(/usr/local/bin/ へのコピー)
本スクリプトは管理者用ツールとして /usr/local/bin/ に配置することを推奨しています。
Windows PC で ZIP をダウンロードした後、展開したスクリプト(create_students.py) を
USB メモリー経由で Linux Mint にコピーします。
手順 1:Windows で ZIP をダウンロードし、展開する
- 本サイトから create_students.zip をダウンロード
- ZIP を展開し、script フォルダ内の
create_students.pyを取り出す - USB メモリーに
create_students.pyをコピー
手順 2:Linux Mint に USB を挿す
USB は自動的にデスクトップに表示されます。
例:/media/ユーザー名/USBNAME/
手順 3:スクリプトを /usr/local/bin/ にコピー
sudo cp /media/ユーザー名/USBNAME/create_students.py /usr/local/bin/
手順 4:実行権限を付与
sudo chmod +x /usr/local/bin/create_students.py
手順 5:どこからでも実行可能に
sudo create_students.py
/usr/local/bin/ は Linux の標準的な管理者用スクリプト置き場であり、 教育現場での再現性が高く、管理もしやすいため推奨しています。
1. このスクリプトでできること
- CSV の一覧から Linux ユーザーを一括作成
- /var/www/html/<folder> に受講生フォルダを作成
- 所有者・パーミッション設定を自動化
- Maildir が無い場合は自動作成
- FTP・メール・Web のユーザー管理を統合
2. CSV の形式
CSV の 1 行目(ヘッダー行)は 必須 です。
以下のような形式で作成してください。
folder,username,password
pc01,pc01,pc01
pc02,pc02,pc02
pc03,pc03,pc03
1列目:フォルダ名
2列目:Linux ユーザー名
3列目:パスワード
※ 1 行目の folder,username,password は必ず入れてください。
3. 実行方法
create_students.py は sudo で実行すると CSV 選択ダイアログが開く 仕組みになっています。 コマンドラインで CSV を指定する必要はありません。
1. 実行権限を付ける
sudo chmod +x /usr/local/bin/create_students.py
2. スクリプトを実行する
sudo create_students.py
実行すると、次のような CSV ファイル選択画面 が表示されます。 ここから CSV を選ぶだけで処理が開始されます。
ステップ 1:最初に表示される画面
最初はホームディレクトリが表示されます。 ここには USB メモリは表示されません。
ステップ 2:右上の「上向き矢印」でフォルダを上がる
USB メモリは /media/ユーザー名/USB名/ にあります。
右上の 上向き矢印 をクリックして階層を上がります。
ステップ 3:media → ユーザー名 → USB メモリ名 の順に開く
USB メモリに保存した CSV が表示されます。 選択して「Open」を押すと処理が開始されます。
※ /usr/local/bin/ に置いた場合、./ は不要です。
PATH に含まれているため、通常のコマンドと同じように実行できます。
(参考)カレントディレクトリから実行する場合
スクリプトがカレントディレクトリにある場合のみ、次のように実行します。
sudo ./create_students.py
4. コード全文(著作権表記入り)
コード全文を表示
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Created by Inajin (InaPC Linux Lab)
# AI(Microsoft Copilot)との共同制作教材
#
# Copyright (c) 2026 Inajin
# 本スクリプトは教育目的での利用・改変を自由に行えます。
# ただし、著作権表記は削除せず残してください。
#
import csv
import os
import subprocess
import sys
import pwd
from datetime import datetime
from tkinter import Tk, filedialog
DOCUMENT_ROOT = "/var/www/html"
LOG_FILE = "/var/log/create_students.log"
def log(message):
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
with open(LOG_FILE, "a") as f:
f.write(f"[{timestamp}] {message}\n")
print(message)
def select_csv_file():
root = Tk()
root.withdraw()
file_path = filedialog.askopenfilename(
title="CSVファイルを選択してください",
filetypes=[("CSV Files", "*.csv")]
)
return file_path
def create_user(user, password, home):
result = subprocess.run(["id", user], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
if result.returncode == 0:
log(f"ユーザー既存のためスキップ: {user}")
else:
subprocess.run(["useradd", "-d", home, "-s", "/usr/sbin/nologin", user])
log(f"ユーザー作成: {user}")
subprocess.run(["bash", "-c", f"echo '{user}:{password}' | chpasswd"])
log(f"パスワード設定: {user}")
def create_folder(path, user):
if not os.path.exists(path):
os.makedirs(path)
log(f"フォルダ作成: {path}")
else:
log(f"フォルダ既存のためスキップ: {path}")
subprocess.run(["chown", f"{user}:{user}", path])
subprocess.run(["chmod", "755", path])
log(f"所有者変更: {user}, パーミッション: 755")
# 所有者チェック(安全装置)
st = os.stat(path)
owner = pwd.getpwuid(st.st_uid).pw_name
if owner == "root":
print(f"エラー:フォルダ {path} の所有者が root です。")
print("sudo なしで実行した可能性があります。")
print("必ず sudo create_students.py で実行してください。")
sys.exit(1)
def main():
# root 権限チェック(安全装置)
if os.geteuid() != 0:
print("エラー:このスクリプトは sudo で実行する必要があります。")
print("例: sudo create_students.py")
sys.exit(1)
csv_path = select_csv_file()
if not csv_path:
print("キャンセルされました。処理を終了します。")
sys.exit(0)
log("=== 受講生フォルダ・FTPユーザー自動作成開始 ===")
log(f"選択された CSV: {csv_path}")
with open(csv_path, newline="", encoding="utf-8") as csvfile:
reader = csv.reader(csvfile)
next(reader)
for row in reader:
folder, user, password = row
folder_path = os.path.join(DOCUMENT_ROOT, folder)
log(f"--- {folder} / {user} の処理開始 ---")
create_user(user, password, folder_path)
create_folder(folder_path, user)
log("=== 全処理完了 ===")
if __name__ == "__main__":
main()