Last active
November 3, 2025 13:15
-
-
Save thiagozs/25ab0777897300b1453f0f05f0034e18 to your computer and use it in GitHub Desktop.
Create user home with password linux
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| # | |
| # Script para criar um usuário no Ubuntu e configurar o diretório HOME | |
| # Autor: Thiago Zilli Sarmento | |
| # Uso: | |
| # sudo ./create_user_with_home.sh <nome_usuario> [grupo_adicional] | |
| # | |
| # Exemplo: | |
| # sudo ./create_user_with_home.sh asapadm sudo | |
| # | |
| set -euo pipefail | |
| # --- Auto-elevação --- | |
| if [[ "$EUID" -ne 0 ]]; then | |
| echo "⚠️ Este script precisa ser executado como root." | |
| echo "🔁 Reexecutando com sudo..." | |
| exec sudo "$0" "$@" | |
| fi | |
| USER_NAME="${1:-}" | |
| GROUP_EXTRA="${2:-}" | |
| if [[ -z "$USER_NAME" ]]; then | |
| echo "❌ Erro: informe o nome do usuário." | |
| echo "Uso: $0 <nome_usuario> [grupo_adicional]" | |
| exit 1 | |
| fi | |
| echo "🚀 Iniciando criação/configuração do usuário '$USER_NAME'..." | |
| # 1. Cria grupo adicional (ex: sudo) se informado e não existir | |
| if [[ -n "$GROUP_EXTRA" ]]; then | |
| if ! getent group "$GROUP_EXTRA" >/dev/null; then | |
| echo "🔧 Criando grupo adicional '$GROUP_EXTRA'..." | |
| groupadd "$GROUP_EXTRA" | |
| fi | |
| fi | |
| # 2. Cria grupo primário se não existir | |
| if ! getent group "$USER_NAME" >/dev/null; then | |
| echo "🔧 Criando grupo primário '$USER_NAME'..." | |
| groupadd "$USER_NAME" | |
| fi | |
| # 3. Cria ou corrige o usuário | |
| if ! id "$USER_NAME" &>/dev/null; then | |
| echo "👤 Criando usuário '$USER_NAME'..." | |
| if [[ -n "$GROUP_EXTRA" ]]; then | |
| useradd -m -s /bin/bash -g "$USER_NAME" -G "$GROUP_EXTRA" "$USER_NAME" | |
| else | |
| useradd -m -s /bin/bash -g "$USER_NAME" "$USER_NAME" | |
| fi | |
| else | |
| echo "ℹ️ Usuário '$USER_NAME' já existe. Verificando grupo..." | |
| CURRENT_GROUP=$(id -gn "$USER_NAME") | |
| if [[ "$CURRENT_GROUP" != "$USER_NAME" ]]; then | |
| echo "🔄 Corrigindo grupo primário para '$USER_NAME'..." | |
| usermod -g "$USER_NAME" "$USER_NAME" | |
| fi | |
| fi | |
| USER_HOME=$(eval echo "~$USER_NAME") | |
| # 4. Garante que o diretório home exista | |
| if [[ ! -d "$USER_HOME" ]]; then | |
| echo "📁 Criando diretório home em $USER_HOME..." | |
| mkdir -p "$USER_HOME" | |
| fi | |
| # 5. Copia arquivos padrão de ambiente | |
| echo "📄 Copiando arquivos padrão..." | |
| cp -n /etc/skel/.bash* "$USER_HOME"/ 2>/dev/null || true | |
| # 6. Ajusta permissões | |
| echo "🔒 Ajustando permissões..." | |
| chown -R "$USER_NAME:$USER_NAME" "$USER_HOME" | |
| chmod 755 "$USER_HOME" | |
| # 7. Define shell padrão como bash | |
| echo "🧰 Definindo shell padrão para /bin/bash..." | |
| chsh -s /bin/bash "$USER_NAME" >/dev/null || true | |
| # 8. Configura senha | |
| echo | |
| read -p "Deseja definir a senha manualmente? (s/n): " -r RESP | |
| if [[ "$RESP" =~ ^[Ss]$ ]]; then | |
| echo "Digite a nova senha para o usuário $USER_NAME:" | |
| passwd "$USER_NAME" | |
| PASSWORD_SET="(definida manualmente)" | |
| else | |
| PASSWORD=$(openssl rand -base64 12) | |
| echo "${USER_NAME}:${PASSWORD}" | chpasswd | |
| PASSWORD_SET="$PASSWORD" | |
| fi | |
| # 9. Mostra resultado final | |
| echo | |
| echo "✅ Usuário '$USER_NAME' configurado com sucesso!" | |
| echo "📁 Home: $USER_HOME" | |
| echo "🐚 Shell: $(getent passwd "$USER_NAME" | cut -d: -f7)" | |
| echo "👥 Grupo primário: $(id -gn "$USER_NAME")" | |
| echo "👥 Grupos extras: $(id -Gn "$USER_NAME" | sed 's/ /\n - /g' | sed '1s/^/ - /')" | |
| if [[ "$PASSWORD_SET" != "(definida manualmente)" ]]; then | |
| echo "🔑 Senha gerada automaticamente: $PASSWORD_SET" | |
| echo "⚠️ Guarde essa senha com segurança — ela não será exibida novamente." | |
| fi | |
| echo | |
| echo "Para testar: sudo su - $USER_NAME" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| # reset-home.sh | |
| # 🔄 Reseta o diretório home de um usuário Linux com diferentes níveis de limpeza. | |
| # Uso: sudo ./reset-home.sh <username> [--safe|--secure|--factory] [--dry-run] [--log] | |
| set -euo pipefail | |
| LOG_ENABLED="no" | |
| LOG_FILE="/var/log/reset-home.log" | |
| MODE="secure" | |
| DRYRUN="no" | |
| # ------------------------------------------------------- | |
| # 🧾 Validações iniciais | |
| # ------------------------------------------------------- | |
| if [[ $(id -u) -ne 0 ]]; then | |
| echo "❌ Execute este script como root (sudo)." >&2 | |
| exit 2 | |
| fi | |
| if [[ $# -lt 1 ]]; then | |
| echo "Uso: $0 <username> [--safe|--secure|--factory] [--dry-run] [--log]" >&2 | |
| exit 2 | |
| fi | |
| USERNAME="$1" | |
| shift || true | |
| # ------------------------------------------------------- | |
| # ⚙️ Parse de argumentos | |
| # ------------------------------------------------------- | |
| while [[ $# -gt 0 ]]; do | |
| case "$1" in | |
| --safe) MODE="safe" ;; | |
| --secure) MODE="secure" ;; | |
| --factory) MODE="factory" ;; | |
| --dry-run|--dryrun) DRYRUN="yes" ;; | |
| --log) LOG_ENABLED="yes" ;; | |
| *) echo "⚠️ Opção desconhecida: $1" >&2 ;; | |
| esac | |
| shift || true | |
| done | |
| # ------------------------------------------------------- | |
| # 🔍 Valida usuário e home | |
| # ------------------------------------------------------- | |
| if ! id "$USERNAME" &>/dev/null; then | |
| echo "❌ Usuário '$USERNAME' não existe." | |
| exit 3 | |
| fi | |
| USER_HOME="$(getent passwd "$USERNAME" | cut -d: -f6)" | |
| if [[ -z "$USER_HOME" || ! -d "$USER_HOME" ]]; then | |
| echo "❌ Diretório home não encontrado: $USER_HOME" | |
| exit 3 | |
| fi | |
| # ------------------------------------------------------- | |
| # 📂 Configura log | |
| # ------------------------------------------------------- | |
| if [[ "$LOG_ENABLED" == "yes" ]]; then | |
| mkdir -p "$(dirname "$LOG_FILE")" | |
| touch "$LOG_FILE" | |
| chmod 600 "$LOG_FILE" | |
| echo "🪵 Logging habilitado em: $LOG_FILE" | |
| fi | |
| log() { | |
| [[ "$LOG_ENABLED" == "yes" ]] && echo "$(date '+%F %T') $*" >> "$LOG_FILE" | |
| } | |
| log_header() { | |
| log "============================================" | |
| log "$(date '+%F %T') - Reset de $USERNAME (modo: $MODE, dry-run: $DRYRUN)" | |
| log "============================================" | |
| } | |
| log_header | |
| # ------------------------------------------------------- | |
| # 🧩 Função auxiliar para executar comandos | |
| # ------------------------------------------------------- | |
| run_cmd() { | |
| local cmd="$*" | |
| if [[ "$DRYRUN" == "yes" ]]; then | |
| echo "💡 [DRY-RUN] $cmd" | |
| log "[DRY-RUN] $cmd" | |
| else | |
| eval "$cmd" | |
| log "$cmd" | |
| fi | |
| } | |
| # ------------------------------------------------------- | |
| # 📋 Cabeçalho informativo | |
| # ------------------------------------------------------- | |
| echo "============================================" | |
| echo " Resetando home de: $USERNAME" | |
| echo " Diretório: $USER_HOME" | |
| echo " Modo: $MODE" | |
| echo " Dry-run: $DRYRUN" | |
| echo " Log: $LOG_ENABLED" | |
| echo "============================================" | |
| # ------------------------------------------------------- | |
| # 🧹 SAFE MODE | |
| # ------------------------------------------------------- | |
| if [[ "$MODE" == "safe" ]]; then | |
| echo "🧹 Modo SAFE: limpando históricos e caches..." | |
| SAFE_ITEMS=( | |
| "$USER_HOME/.bash_history" "$USER_HOME/.zsh_history" | |
| "$USER_HOME/.local/share/fish/fish_history" | |
| "$USER_HOME/.python_history" "$USER_HOME/.node_repl_history" | |
| "$USER_HOME/.sqlite_history" "$USER_HOME/.psql_history" | |
| "$USER_HOME/.mysql_history" "$USER_HOME/.lesshst" | |
| "$USER_HOME/.viminfo" "$USER_HOME/.nano_history" | |
| "$USER_HOME/.cache" "$USER_HOME/.local/share/Trash" | |
| "$USER_HOME/.local/state" "$USER_HOME/tmp" | |
| ) | |
| for item in "${SAFE_ITEMS[@]}"; do | |
| run_cmd "rm -rf -- '$item' 2>/dev/null || true" | |
| done | |
| fi | |
| # ------------------------------------------------------- | |
| # 🧨 SECURE MODE | |
| # ------------------------------------------------------- | |
| if [[ "$MODE" == "secure" ]]; then | |
| echo "🧨 Modo SECURE: limpeza profunda mantendo estrutura..." | |
| REMOVE_DIRS=( | |
| ".ssh" ".gnupg" ".aws" ".docker" ".kube" ".azure" ".oci" | |
| ".gcloud" ".terraform.d" ".ansible" ".pki" ".npm" ".nvm" | |
| ".pyenv" ".cargo" ".rustup" ".local/share/keyrings" | |
| ".password-store" ".mozilla" ".config/chromium" | |
| ".config/google-chrome" ".local/share/recently-used.xbel" | |
| ) | |
| REMOVE_FILES=( | |
| ".bash_history" ".zsh_history" ".python_history" | |
| ".node_repl_history" ".psql_history" ".sqlite_history" | |
| ".lesshst" ".viminfo" ".nano_history" ".gitconfig" | |
| ".git-credentials" ".xsession-errors" ".p10k.zsh" | |
| ) | |
| for d in "${REMOVE_DIRS[@]}"; do | |
| [[ -d "$USER_HOME/$d" ]] && run_cmd "rm -rf '$USER_HOME/$d'" | |
| done | |
| for f in "${REMOVE_FILES[@]}"; do | |
| [[ -f "$USER_HOME/$f" ]] && run_cmd "rm -f '$USER_HOME/$f'" | |
| done | |
| run_cmd "rm -rf '$USER_HOME/.cache' '$USER_HOME/tmp' '$USER_HOME/.local/share/Trash'" | |
| KEEP=( ".bashrc" ".profile" ".bash_logout" ".config" ".local" ) | |
| for item in "$USER_HOME"/.* "$USER_HOME"/*; do | |
| base="$(basename "$item")" | |
| [[ ! -e "$item" ]] && continue | |
| if [[ " ${KEEP[*]} " != *" $base "* && "$base" != "." && "$base" != ".." ]]; then | |
| run_cmd "rm -rf '$item'" | |
| fi | |
| done | |
| echo "🧱 Recriando pastas padrão..." | |
| DEFAULT_DIRS_PT=( "Área de trabalho" "Documentos" "Downloads" "Imagens" "Modelos" "Músicas" "Público" "Vídeos" ) | |
| DEFAULT_DIRS_EN=( "Desktop" "Documents" "Downloads" "Pictures" "Templates" "Music" "Public" "Videos" ) | |
| LANG_CODE="$(locale | grep LANG= | cut -d= -f2 | cut -d_ -f1)" | |
| if [[ "$LANG_CODE" == "pt" ]]; then | |
| DEFAULT_DIRS=("${DEFAULT_DIRS_PT[@]}") | |
| else | |
| DEFAULT_DIRS=("${DEFAULT_DIRS_EN[@]}") | |
| fi | |
| for d in "${DEFAULT_DIRS[@]}"; do | |
| [[ ! -d "$USER_HOME/$d" ]] && run_cmd "mkdir -p '$USER_HOME/$d'" | |
| done | |
| fi | |
| # ------------------------------------------------------- | |
| # 💣 FACTORY MODE | |
| # ------------------------------------------------------- | |
| if [[ "$MODE" == "factory" ]]; then | |
| echo "💣 Modo FACTORY: removendo tudo e restaurando de /etc/skel..." | |
| run_cmd "rm -rf '$USER_HOME'/* '$USER_HOME'/.[!.]* '$USER_HOME'/..?*" | |
| run_cmd "cp -rT /etc/skel '$USER_HOME'" | |
| fi | |
| # ------------------------------------------------------- | |
| # 🔧 Pós-limpeza | |
| # ------------------------------------------------------- | |
| echo "🧩 Ajustando permissões..." | |
| run_cmd "chown -R $USERNAME:$USERNAME '$USER_HOME'" | |
| run_cmd "chmod 700 '$USER_HOME'" | |
| if [[ "$DRYRUN" != "yes" ]]; then | |
| echo "🧠 Encerrando sessões ativas de $USERNAME..." | |
| pkill -TERM -u "$USERNAME" 2>/dev/null || true | |
| loginctl terminate-user "$USERNAME" 2>/dev/null || true | |
| fi | |
| echo | |
| echo "✅ Reset concluído para $USERNAME (modo: $MODE)${DRYRUN:+ [SIMULADO]}." | |
| echo "============================================" | |
| log "Concluído reset de $USERNAME (modo: $MODE)" | |
| exit 0 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment