-
Notifications
You must be signed in to change notification settings - Fork 766
shell scripting project #1 #12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
WalkthroughAdds a new interactive Bash script Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant Admin as Admin (interactive)
participant Script as pam-main.sh
participant Sys as System (user/group/tar)
Admin->>Script: Run script / select option
alt Not root
Script->>Admin: "Must run as root" and exit
else Root (initial check passes)
Admin->>Script: Choose option (1..10)
alt 1: Add user
Script->>Admin: Prompt for full name
Admin->>Script: Provide name
Script->>Sys: useradd -m -s /bin/bash
Script->>Sys: generate password -> chpasswd -> passwd -e
Sys-->>Script: OK/ERR
Script-->>Admin: Result
else 2: Delete user
Script->>Sys: getent passwd (UID>=1000) -> list
Admin->>Script: Select & confirm username
Script->>Sys: userdel -r
Sys-->>Script: OK/ERR
Script-->>Admin: Result
else 3..7: Modify user (groups/shell/disable/enable/sudo)
Script->>Sys: usermod / chsh / group modifications
Sys-->>Script: OK/ERR
Script-->>Admin: Result
else 8: Add group
Script->>Sys: groupadd (if not exists)
Sys-->>Script: OK/ERR
Script-->>Admin: Result
else 9: Backup directories
Script->>Admin: Prompt absolute path
Admin->>Script: Provide path
Script->>Sys: tar -> /opt/dir_backups/<user>-<ts>.tar.gz
Sys-->>Script: OK/ERR
Script-->>Admin: Result
else 10: Exit
Script-->>Admin: Exit loop and terminate
end
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Pre-merge checks (2 passed, 1 inconclusive)❌ Failed checks (1 inconclusive)
✅ Passed checks (2 passed)
Poem
✨ Finishing touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 11
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
day02/pam-main.sh (1)
1-154: Fix shebang and quoting issues
- day02/pam-main.sh line 1: replace
#/bin/bashwith a valid shebang (e.g.#!/usr/bin/env bash).- Quote every variable expansion (SC2086), e.g. use
"${username}","${grpname}","${dirback}".- Replace legacy backticks with
$(…)command substitutions (SC2006).- Add
-rto allreadinvocations to prevent backslash mangling (SC2162).- Use
[[ … ]]for conditional tests instead of[…]where recommended (SC2292).- Remove or utilize the unused
WHITEcolor constant (SC2034).
🧹 Nitpick comments (3)
day02/pam-main.sh (3)
10-10: Remove unused color constant WHITENot used anywhere; drop it or use consistently for output.
-WHITE='\033[1;37m'
73-81: Prefer usermod -s for shell changes; handle unsupported shells
- chsh may fail if shell not in /etc/shells; check errors.
- Quote variables and add a default else branch.
-if [ "$curr_shell" = "/bin/sh" ]; then - chsh -s /bin/bash "$username" +if [[ "$curr_shell" == "/bin/sh" ]]; then + usermod -s /bin/bash "$username" && \ echo "$username's shell is successfully changed to bash" echo "-------------------------------------------------" -elif [ "$curr_shell" = "/bin/bash" ]; then - chsh -s /bin/sh "$username" +elif [[ "$curr_shell" == "/bin/bash" ]]; then + usermod -s /bin/sh "$username" && \ echo "$username's shell is successfully changed to sh" echo "-----------------------------------------------" +else + echo "Unsupported current shell '$curr_shell'; no change made." fi
107-114: Mirror portability for enabling loginUse usermod -s and check success.
-echo "Changing $username shell to /bin/bash" -chsh -s /bin/bash "$username" +echo "Changing $username shell to /bin/bash" +usermod -s /bin/bash "$username" echo "$username's shell is successfully activated to bash"
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
day02/pam-main.sh(1 hunks)
🧰 Additional context used
🪛 Shellcheck (0.10.0)
day02/pam-main.sh
[error] 1-1: Use #!, not just #, for the shebang.
(SC1113)
[warning] 10-10: WHITE appears unused. Verify use (or export if used externally).
(SC2034)
🔇 Additional comments (1)
day02/pam-main.sh (1)
1-154: Target distro and commands: confirm Debian/Ubuntu vs RHEL/CentOSYou mix Debian-only tools (deluser, addgroup) with portable ones. Confirm target(s) and adjust accordingly, or branch by detection.
Would you confirm the Linux distributions you want to support? If multi-distro, I can add a small helper that maps commands per OS (ID from /etc/os-release) and detects sudo/wheel, nologin path, etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
♻️ Duplicate comments (2)
day02/pam-main.sh (2)
1-1: Malformed shebang; enable strict mode earlyCurrent line prevents execution under Bash and misses safe options.
-#/bin/bash +#!/usr/bin/env bash +set -Eeuo pipefail +IFS=$'\n\t'
74-86: Group selection mismatch: list source ≠ pick sourceYou list groups via getent (all groups) but pick via /etc/group filtered by GID>=1000, so indices don’t match. Result: wrong group may be chosen.
-echo "------------------Group List-------------------------" -getent group | awk -F: '{print $1}' | nl -w1 -s". " +echo "------------------Group List-------------------------" +getent group | awk -F: '{print $1}' | nl -w1 -s". " read -p "Select the existing user NUMBER: " choice read -p "Select the group NUMBER to be added: " gchoice -username=$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p") -grpname=$(awk -F: '$3 >= 1000 {print $1}' /etc/group | sed -n "${gchoice}p") +username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")" +grpname="$(getent group | awk -F: '{print $1}' | sed -n "${gchoice}p")" if [[ -n "${username:-}" && -n "${grpname:-}" ]]; then
🧹 Nitpick comments (5)
day02/pam-main.sh (5)
94-107: Prompt mismatch and prefer usermod -s over chshPrompt asks for username but expects a number. Use usermod -s for consistency.
-read -p "Select the existing username: " choice +read -p "Select the existing user NUMBER: " choice username=$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p") curr_shell=$(getent passwd "$username" | cut -d: -f7) if [ "$curr_shell" = "/bin/sh" ]; then - chsh -s /bin/bash "$username" + usermod -s /bin/bash "$username" echo "$username's shell is successfully changed to bash" echo "-------------------------------------------------" elif [ "$curr_shell" = "/bin/bash" ]; then - chsh -s /bin/sh "$username" + usermod -s /bin/sh "$username" echo "$username's shell is successfully changed to sh" echo "-----------------------------------------------" fi
113-122: Consistent prompts and enable using usermod -sAlign prompt with numbered list and prefer usermod -s.
-read -p "Select the existing username: " choice +read -p "Select the existing user NUMBER: " choice @@ - echo "Changing $username shell to /bin/bash" - chsh -s /bin/bash "$username" + echo "Changing $username shell to /bin/bash" + usermod -s /bin/bash "$username" echo "$username's shell is successfully activated to bash"Also applies to: 130-139
147-153: Prompt mismatch for sudo group selectionMenu uses numbers; prompt says “Enter the existing username”. Fix text.
-read -p "Enter the existing username: " choice +read -p "Select the existing user NUMBER: " choice
169-179: Backup: verify selected user and absolute path; handle empty usernameMinor guardrails to avoid creating “_timestamp.tar.gz”.
username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")" -read -r -p "Specify the absolute path of the directory to be backed up: " dirback -if [[ -d "$dirback" ]]; then +[[ -n "${username:-}" ]] || { echo "Invalid user selection."; break; } +read -r -p "Specify the absolute path of the directory to be backed up: " dirback +if [[ "$dirback" = /* && -d "$dirback" ]]; then ts="$(date +%F_%H-%M-%S)" tar -czf "/opt/dir_backups/${username}_$ts.tar.gz" -C "$dirback" . >/dev/null 2>&1 && \ echo "Backup completed successfully" || echo "Backup failed" else echo "Directory '$dirback' not found." fi
188-190: Exit cleanlyUsing break relies on loop structure; exit 0 is clearer.
- break; + exit 0
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
day02/pam-main.sh(1 hunks)
🧰 Additional context used
🪛 Shellcheck (0.10.0)
day02/pam-main.sh
[error] 1-1: Use #!, not just #, for the shebang.
(SC1113)
[error] 16-16: Couldn't parse this while loop. Fix to allow more checks.
(SC1073)
[error] 16-16: Couldn't find 'done' for this 'do'.
(SC1061)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
♻️ Duplicate comments (7)
day02/pam-main.sh (7)
1-1: Fix malformed shebang and enable safe Bash options earlyUse a valid shebang and fail fast with safe defaults.
Apply:
-#/bin/bash +#!/usr/bin/env bash +set -Eeuo pipefail +IFS=$'\n\t'
16-20: Remove tight no-op loop that busy-spins before the menuThis while-loop repeatedly re-checks EUID and does nothing when root.
-while true; do -if [[ $EUID -ne 0 ]]; then - echo "This script must be run as root (sudo)."; exit 1 -fi -done
21-21: Run the root check once before entering the menu loopPlace EUID check above the main loop.
+if [[ $EUID -ne 0 ]]; then + echo "This script must be run as root (sudo)." >&2 + exit 1 +fi while true; do
82-90: Align prompts with number selection, validate inputs, and pick group from the same listFix prompt text, add numeric checks, and use
getent groupfor selection (list and pick source should match).-read -p "Select the existing user NUMBER: " choice -read -p "Select the group NUMBER to be added: " gchoice -username=$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p") -grpname=$(awk -F: '$3 >= 1000 {print $1}' /etc/group | sed -n "${gchoice}p") -if [[ -n "${username:-}" && -n "${grpname:-}" ]]; then - usermod -aG "$grpname" "$username" && echo "$username added to group $grpname" -else - echo "Invalid selection." -fi +read -r -p "Select the existing user NUMBER: " choice +[[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid user selection."; continue; } +read -r -p "Select the group NUMBER to be added: " gchoice +[[ "$gchoice" =~ ^[0-9]+$ ]] || { echo "Invalid group selection."; continue; } +username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")" +grpname="$(getent group | awk -F: '{print $1}' | sed -n "${gchoice}p")" +if [[ -n "${username:-}" && -n "${grpname:-}" ]]; then + usermod -aG "$grpname" "$username" && echo "$username added to group $grpname" +else + echo "Invalid selection." +fi
100-111: Prompt/selection mismatch; add validation before toggling shellPrompt says “username” but expects a number; also guard empty picks.
- read -p "Select the existing username: " choice - username=$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p") + read -r -p "Select the existing user NUMBER: " choice + [[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; } + username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")" + [[ -n "${username:-}" ]] || { echo "Invalid selection."; continue; } - curr_shell=$(getent passwd "$username" | cut -d: -f7) - if [ "$curr_shell" = "/bin/sh" ]; then + curr_shell=$(getent passwd "$username" | cut -d: -f7) + if [[ "$curr_shell" == "/bin/sh" ]]; then chsh -s /bin/bash "$username" echo "$username's shell is successfully changed to bash" echo "-------------------------------------------------" - elif [ "$curr_shell" = "/bin/bash" ]; then + elif [[ "$curr_shell" == "/bin/bash" ]]; then chsh -s /bin/sh "$username" echo "$username's shell is successfully changed to sh" echo "-----------------------------------------------" fi
153-157: Prompt/selection mismatch and missing validation for sudo-group addSwitch to number-based prompt and validate.
- read -p "Enter the existing username: " choice - username=$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p") + read -r -p "Select the existing user NUMBER: " choice + [[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; } + username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")" + [[ -n "${username:-}" ]] || { echo "Invalid selection."; continue; }
176-185: Harden backup input handling and filenameValidate selection, guard empty username, and avoid empty prefix in archive name.
- read -r -p "Select the user NUMBER to associate with the backup: " choice - username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")" - read -r -p "Specify the absolute path of the directory to be backed up: " dirback - if [[ -d "$dirback" ]]; then - ts="$(date +%F_%H-%M-%S)" - tar -czf "/opt/dir_backups/${username}_$ts.tar.gz" -C "$dirback" . >/dev/null 2>&1 && \ + read -r -p "Select the user NUMBER to associate with the backup: " choice + [[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; } + username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")" + [[ -n "${username:-}" ]] || { echo "Invalid user selection."; continue; } + read -r -p "Specify the absolute path of the directory to be backed up: " dirback + if [[ -d "$dirback" ]]; then + ts="$(date +%F_%H-%M-%S)" + tar -czf "/opt/dir_backups/${username:-unknown}_$ts.tar.gz" -C "$dirback" . >/dev/null 2>&1 && \ echo "Backup completed successfully" || echo "Backup failed"
🧹 Nitpick comments (2)
day02/pam-main.sh (2)
44-50: Avoid printing plaintext temporary passwords to the terminalStore in a root-only log instead of echoing the secret.
- echo "$username created. Temporary password: $randpass (will be forced to change on first login)" + log="/root/pam-main-passwords.log" + { umask 077; printf '%s:%s\n' "$username" "$randpass" >> "$log"; } + echo "$username created. Temporary password saved to $log (will be forced to change on first login)"
9-9: Remove unused color variable (ShellCheck SC2034)
WHITEis defined but not used.-WHITE='\033[1;37m'
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
day02/pam-main.sh(1 hunks)
🧰 Additional context used
🪛 Shellcheck (0.10.0)
day02/pam-main.sh
[error] 1-1: Use #!, not just #, for the shebang.
(SC1113)
[warning] 9-9: WHITE appears unused. Verify use (or export if used externally).
(SC2034)
🔇 Additional comments (1)
day02/pam-main.sh (1)
121-126: Good portability on login disableDetecting
nologindynamically and usingusermod -sis portable and correct. LGTM.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (6)
day02/pam-main.sh (6)
1-1: Fix malformed shebang and enable safe Bash optionsScript won’t run under Bash as written; add strict mode early.
Apply:
-#/bin/bash +#!/usr/bin/env bash +set -Eeuo pipefail +IFS=$'\n\t'
16-20: Remove infinite pre-loop; perform root check once before the menuThis while-true block busy-loops forever for root users.
Apply:
-while true; do -if [[ $EUID -ne 0 ]]; then - echo "This script must be run as root (sudo)."; exit 1 -fi -done +if [[ $EUID -ne 0 ]]; then + echo "This script must be run as root (sudo)." >&2 + exit 1 +fi
38-38: Don’t exit the menu when the user already exists; continue insteadbreak exits the whole menu loop.
- echo "User '$username' already exists."; echo "-----------------------------------------------"; unset username; break + echo "User '$username' already exists."; echo "-----------------------------------------------"; unset username; continue
81-86: Fix group selection source mismatch (list via getent, select via /etc/group)You list groups with getent but index into /etc/group (different orders) → wrong group.
-read -p "Select the existing user NUMBER: " choice -read -p "Select the group NUMBER to be added: " gchoice -username=$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p") -grpname=$(awk -F: '$3 >= 1000 {print $1}' /etc/group | sed -n "${gchoice}p") +read -r -p "Select the existing user NUMBER: " choice +[[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid user selection."; continue; } +read -r -p "Select the group NUMBER to be added: " gchoice +[[ "$gchoice" =~ ^[0-9]+$ ]] || { echo "Invalid group selection."; continue; } +username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")" +grpname="$(getent group | awk -F: '{print $1}' | sed -n "${gchoice}p")"
118-126: Validate numeric selection for “Disable Login”Match prompt style and guard empty username.
-read -p "Select the existing username: " choice -username=$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p") -if getent passwd "$username" > /dev/null; then +read -r -p "Select the existing user NUMBER: " choice +[[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; } +username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")" +if [[ -n "${username:-}" ]] && getent passwd "$username" > /dev/null; then
151-158: Add sudo: use NUMBER prompt + validation and guard empty usernamePrevents accidental empty add.
-read -p "Enter the existing username: " choice -username=$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p") +read -r -p "Select the existing user NUMBER: " choice +[[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; } +username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")" admin_group="$(getent group sudo >/dev/null 2>&1 && echo sudo || echo wheel)" -usermod -aG "$admin_group" "$username" -echo "$username added to $admin_group group." +if [[ -n "${username:-}" ]]; then + usermod -aG "$admin_group" "$username" && echo "$username added to $admin_group group." +else + echo "Invalid selection." +fi
🧹 Nitpick comments (2)
day02/pam-main.sh (2)
176-183: Backups: validate selected user and show archive pathMinor UX hardening.
-username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")" +username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")" +[[ -n "${username:-}" ]] || { echo "Invalid selection."; continue; } read -r -p "Specify the absolute path of the directory to be backed up: " dirback if [[ -d "$dirback" ]]; then ts="$(date +%F_%H-%M-%S)" - tar -czf "/opt/dir_backups/${username}_$ts.tar.gz" -C "$dirback" . >/dev/null 2>&1 && \ - echo "Backup completed successfully" || echo "Backup failed" + archive="/opt/dir_backups/${username}_$ts.tar.gz" + tar -czf "$archive" -C "$dirback" . >/dev/null 2>&1 && \ + echo "Backup completed: $archive" || echo "Backup failed"
9-9: Remove unused color variable WHITEClean up per ShellCheck SC2034.
-WHITE='\033[1;37m'
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
day02/pam-main.sh(1 hunks)
🧰 Additional context used
🪛 Shellcheck (0.10.0)
day02/pam-main.sh
[error] 1-1: Use #!, not just #, for the shebang.
(SC1113)
[warning] 9-9: WHITE appears unused. Verify use (or export if used externally).
(SC2034)
🔇 Additional comments (2)
day02/pam-main.sh (2)
121-125: Good: portable nologin detection and consistent usermod usageThis improves distro compatibility.
54-67: Good: safer delete flow with validation and self-delete guardNumeric validation, confirmation, and userdel -r are appropriate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (5)
day02/pam-main.sh (5)
1-1: Fix shebang and enable strict mode early
Use a valid shebang and safe bash options at the top.-#/bin/bash +#!/usr/bin/env bash +set -Eeuo pipefail +IFS=$'\n\t'
16-21: Remove infinite pre-loop; run root check once, then enter menu
Current while/do around the EUID check spins forever (no body/break) and prevents reaching the menu.-while true; do -if [[ $EUID -ne 0 ]]; then - echo "This script must be run as root (sudo)."; exit 1 -fi -done -while true; do +if [[ $EUID -ne 0 ]]; then + echo "This script must be run as root (sudo)." >&2 + exit 1 +fi +while true; do
35-39: Don’t exit the menu when user exists; continue instead
Using break exits the whole menu loop.- echo "User '$username' already exists."; echo "-----------------------------------------------"; unset username; break + echo "User '$username' already exists." + echo "-----------------------------------------------" + unset username + continue
155-166: Add-to-sudo: prompt mismatch and missing validation
Input expects a NUMBER but prompt asks for username; also validate selection and handle empty username.-read -p "Enter the existing username: " choice -username=$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p") +read -r -p "Select the existing user NUMBER: " choice +[[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; } +username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")" +if [[ -z "${username:-}" ]]; then echo "Invalid selection."; continue; fi admin_group="$(getent group sudo >/dev/null 2>&1 && echo sudo || echo wheel)" usermod -aG "$admin_group" "$username" echo "$username added to $admin_group group."
121-129: Prompt/validation mismatch for ‘Disable Login’
Prompt says “username” but expects a NUMBER; also missing numeric validation. Align prompt and validate.-read -p "Select the existing username: " choice -username=$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p") +read -r -p "Select the existing user NUMBER: " choice +[[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; } +username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")" -if getent passwd "$username" > /dev/null; then +if [[ -n "${username:-}" ]] && getent passwd "$username" > /dev/null; then
🧹 Nitpick comments (4)
day02/pam-main.sh (4)
139-147: Minor: make prompt consistent with NUMBER input
Message says “user” but you require a number; adjust for clarity.-read -rp "Select the existing user: " choice +read -rp "Select the existing user NUMBER: " choiceAlso applies to: 141-141
178-187: Backup: validate selection and guard empty username
Add NUMBER validation and ensure username is non-empty before naming the archive.-read -r -p "Select the user NUMBER to associate with the backup: " choice -username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")" +read -r -p "Select the user NUMBER to associate with the backup: " choice +[[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; } +username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")" @@ - ts="$(date +%F_%H-%M-%S)" - tar -czf "/opt/dir_backups/${username}_$ts.tar.gz" -C "$dirback" . >/dev/null 2>&1 && \ + ts="$(date +%F_%H-%M-%S)" + name="${username:-unknown}" + tar -czf "/opt/dir_backups/${name}_$ts.tar.gz" -C "$dirback" . >/dev/null 2>&1 && \Also applies to: 180-186
9-9: Remove unused color or use it
WHITE is defined but unused.-WHITE='\033[1;37m' +# WHITE='\033[1;37m' # unused
22-33: Optional: factor repeated listing/selection into helpers
You duplicate “list users”, “validate number”, and “map selection” in several cases. Extract small functions to reduce mistakes and drift.Happy to propose a minimal helper set (list_users, select_from_list, list_groups) if you want.
Also applies to: 199-203
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
day02/pam-main.sh(1 hunks)
🧰 Additional context used
🪛 Shellcheck (0.10.0)
day02/pam-main.sh
[error] 1-1: Use #!, not just #, for the shebang.
(SC1113)
[warning] 9-9: WHITE appears unused. Verify use (or export if used externally).
(SC2034)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (6)
day02/pam-main.sh (6)
38-38: Don’t exit menu when user exists; continue insteadKeeps UX consistent with other invalid selections.
- echo "User '$username' already exists."; echo "-----------------------------------------------"; unset username; break + echo "User '$username' already exists."; echo "-----------------------------------------------"; unset username; continue
1-1: Fix malformed shebang and enable strict mode earlyScript won’t run under Bash as-is; also add safe options.
-#/bin/bash +#!/usr/bin/env bash +set -Eeuo pipefail +IFS=$'\n\t'
81-89: Fix group selection: validate gchoice and resolve from same list sourceCurrently validates $choice twice and indexes /etc/group (GID>=1000) while listing via getent; indexes can mismatch.
- getent group | awk -F: '{print $1}' | nl -w1 -s". " + getent group | awk -F: '{print $1}' | nl -w1 -s". " @@ - read -p "Select the group NUMBER to be added: " gchoice - [[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; } + read -p "Select the group NUMBER to be added: " gchoice + [[ "$gchoice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; } @@ - grpname=$(awk -F: '$3 >= 1000 {print $1}' /etc/group | sed -n "${gchoice}p") - if [[ -n "${username}" && -n "${grpname}" ]]; then + grpname="$(getent group | awk -F: '{print $1}' | sed -n "${gchoice}p")" + if [[ -n "${username:-}" && -n "${grpname:-}" ]]; then usermod -aG "$grpname" "$username" && echo "$username added to group $grpname"
125-135: Option 5 (Disable login): prompt/validation mismatch; guard selectionPrompt asks for username but expects a number; add numeric validation and consistent flow.
- read -p "Select the existing username: " choice - username=$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p") - if getent passwd "$username" > /dev/null; then + read -r -p "Select the existing user NUMBER: " choice + [[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; } + username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")" + if [[ -n "${username:-}" ]] && getent passwd "$username" > /dev/null; then nologin_path="$(command -v nologin || echo /sbin/nologin)" echo "Changing $username shell to $nologin_path" usermod -s "$nologin_path" "$username" echo "$username's login disabled." echo "-------------------------------" else - echo "User $username not found!" + echo "Invalid selection." fi
159-163: Option 7 (Add to sudo/wheel): prompt/validation mismatch; add checksReads NUMBER but prompts for username; add validation and skip on invalid.
- read -p "Enter the existing username: " choice - username=$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p") - admin_group="$(getent group sudo >/dev/null 2>&1 && echo sudo || echo wheel)" - usermod -aG "$admin_group" "$username" - echo "$username added to $admin_group group." + read -r -p "Select the existing user NUMBER: " choice + [[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; } + username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")" + if [[ -n "${username:-}" ]]; then + admin_group="$(getent group sudo >/dev/null 2>&1 && echo sudo || echo wheel)" + usermod -aG "$admin_group" "$username" && echo "$username added to $admin_group group." + else + echo "Invalid selection." + fi
16-21: Remove infinite root-check loop; check once before menuCurrent while/do loop spins forever when EUID==0 and never reaches the menu.
-while true; do -if [[ $EUID -ne 0 ]]; then - echo "This script must be run as root (sudo)."; exit 1 -fi -done +if [[ $EUID -ne 0 ]]; then + echo "This script must be run as root (sudo)." >&2; exit 1 +fi
🧹 Nitpick comments (2)
day02/pam-main.sh (2)
182-189: Option 9 (Backup): validate selection; handle empty username; safer filenameAvoid empty username and ensure numeric selection. Optionally keep “unknown” prefix.
- read -r -p "Select the user NUMBER to associate with the backup: " choice - username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")" + read -r -p "Select the user NUMBER to associate with the backup: " choice + [[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; } + username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")" @@ - tar -czf "/opt/dir_backups/${username}_$ts.tar.gz" -C "$dirback" . >/dev/null 2>&1 && \ + tar -czf "/opt/dir_backups/${username:-unknown}_$ts.tar.gz" -C "$dirback" . >/dev/null 2>&1 && \ echo "Backup completed successfully" || echo "Backup failed"
9-9: Remove unused WHITE color var (SC2034)Silences ShellCheck warning.
-WHITE='\033[1;37m'
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
day02/pam-main.sh(1 hunks)
🧰 Additional context used
🪛 Shellcheck (0.10.0)
day02/pam-main.sh
[error] 1-1: Use #!, not just #, for the shebang.
(SC1113)
[warning] 9-9: WHITE appears unused. Verify use (or export if used externally).
(SC2034)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (5)
day02/pam-main.sh (5)
1-1: Fix shebang and enable strict mode earlyUse a valid shebang and turn on safe Bash options to fail fast.
Apply:
-#/bin/bash +#!/usr/bin/env bash +set -Eeuo pipefail +IFS=$'\n\t'
33-38: Don’t exit the menu when user already exists; use continuebreak exits the main loop; you want to return to the menu.
- echo "User '$username' already exists."; echo "-----------------------------------------------"; unset username; break + echo "User '$username' already exists." + echo "-----------------------------------------------" + unset username + continue
76-87: Group selection: validate group number and resolve from the same list sourceYou validate choice, but not gchoice; also you list groups via getent yet resolve via /etc/group, which can index-mismatch.
getent group | awk -F: '$3 >= 1000 {print $1}' | nl -w1 -s". " -read -p "Select the existing user NUMBER: " choice - [[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; } -read -p "Select the group NUMBER to be added: " gchoice - [[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; } -username=$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p") -grpname=$(awk -F: '$3 >= 1000 {print $1}' /etc/group | sed -n "${gchoice}p") +read -r -p "Select the existing user NUMBER: " choice +[[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; } +read -r -p "Select the group NUMBER to be added: " gchoice +[[ "$gchoice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; } +username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")" +grpname="$(getent group | awk -F: '$3 >= 1000 {print $1}' | sed -n "${gchoice}p")" -if [[ -n "${username}" && -n "${grpname}" ]]; then +if [[ -n "${username:-}" && -n "${grpname:-}" ]]; then
155-163: Prompt/selection mismatch and missing validationAsks for username but uses numeric index; add validation and ensure username resolved.
-read -p "Enter the existing username: " choice -username=$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p") +read -r -p "Select the existing user NUMBER: " choice +[[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; } +username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")" +[[ -n "${username:-}" ]] || { echo "Invalid selection."; continue; } admin_group="$(getent group sudo >/dev/null 2>&1 && echo sudo || echo wheel)" usermod -aG "$admin_group" "$username"
121-129: Prompt/selection mismatch: expects NUMBER but asks for username; add validationCurrently asks for “username” but uses sed index; this will break on non-numeric input.
-read -p "Select the existing username: " choice -username=$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p") +read -r -p "Select the existing user NUMBER: " choice +[[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; } +username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")" -if getent passwd "$username" > /dev/null; then +if [[ -n "${username:-}" ]] && getent passwd "$username" > /dev/null; then
🧹 Nitpick comments (7)
day02/pam-main.sh (7)
6-12: Remove unused color or use itWHITE is defined but not used; drop it or use it to keep things tidy. ShellCheck SC2034.
-WHITE='\033[1;37m'
16-19: Root check LGTMRuns once before the loop and exits non-root. Consider sending message to stderr, but OK as-is.
- echo "This script must be run as root (sudo)." + echo "This script must be run as root (sudo)." >&2
31-31: Read without backslash escapesUse -r to avoid interpreting backslashes in input.
-read -p "Select the option: " choice +read -r -p "Select the option: " choice
39-46: Avoid printing passwords to the console; store securely or prompt to setEchoing the temporary password is risky (shoulder-surfing/logging). Prefer saving to a root-readable file or forcing the admin to set it interactively.
- printf '%s:%s\n' "$username" "$randpass" | chpasswd + printf '%s:%s\n' "$username" "$randpass" | chpasswd passwd --expire "$username" >/dev/null - echo "$username created. Temporary password: $randpass (will be forced to change on first login)" + passfile="/root/user_temp_passwords.csv" + umask 077 + printf '%s,%s\n' "$username" "$randpass" >> "$passfile" + echo "$username created. Temporary password stored at $passfile (will be forced to change on first login)"
51-70: User deletion flow looks solid; consider terminating active sessionsOptionally terminate processes/sessions before deletion to avoid leftover processes.
- if userdel -r "$username" >/dev/null 2>&1; then + loginctl terminate-user "$username" >/dev/null 2>&1 || pkill -KILL -u "$username" >/dev/null 2>&1 || true + if userdel -r "$username" >/dev/null 2>&1; then echo "$username deleted."
98-120: Shell toggle: optionally restrict to valid shellsConsider checking against /etc/shells before toggling, and handle usermod failures explicitly.
- if [[ "$curr_shell" == "/bin/sh" ]]; then + if ! grep -qxF "/bin/bash" /etc/shells || ! grep -qxF "/bin/sh" /etc/shells; then + echo "Warning: /etc/shells does not include expected shells." + fi + if [[ "$curr_shell" == "/bin/sh" ]]; then usermod -s /bin/bash "$username" && echo "$username's shell changed to bash"
139-146: Align prompt with numeric selectionThe input is validated as a number; update the prompt to match.
-read -rp "Select the existing user: " choice +read -rp "Select the existing user NUMBER: " choice
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
day02/pam-main.sh(1 hunks)
🧰 Additional context used
🪛 Shellcheck (0.10.0)
day02/pam-main.sh
[error] 1-1: Use #!, not just #, for the shebang.
(SC1113)
[warning] 9-9: WHITE appears unused. Verify use (or export if used externally).
(SC2034)
🔇 Additional comments (1)
day02/pam-main.sh (1)
200-204: Default branch OKInvalid options handled and loop continues. Good.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (4)
day02/pam-main.sh (4)
1-1: Fix shebang and enable strict mode earlyCurrent shebang is malformed; add a valid one and harden execution.
-#/bin/bash +#!/usr/bin/env bash +set -Eeuo pipefail +IFS=$'\n\t'
34-38: Don’t exit the menu when user existsUsing break here exits the main loop. Use continue so the menu keeps running.
- echo "User '$username' already exists."; echo "-----------------------------------------------"; unset username; break + echo "User '$username' already exists." + echo "-----------------------------------------------" + unset username + continue
80-87: Fix group selection validation and source mismatch
- Validation checks $choice twice; second should validate $gchoice.
- You list groups via getent but resolve from /etc/group; indexes can diverge. Resolve from the same list you printed.
- getent group | awk -F: '$3 >= 1000 {print $1}' | nl -w1 -s". " - read -p "Select the existing user NUMBER: " choice - [[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; } - read -p "Select the group NUMBER to be added: " gchoice - [[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; } - username=$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p") - grpname=$(awk -F: '$3 >= 1000 {print $1}' /etc/group | sed -n "${gchoice}p") + groups_list="$(getent group | awk -F: '{print $1}')" + echo "$groups_list" | nl -w1 -s". " + read -r -p "Select the existing user NUMBER: " choice + [[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; } + read -r -p "Select the group NUMBER to be added: " gchoice + [[ "$gchoice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; } + username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")" + grpname="$(printf '%s\n' "$groups_list" | sed -n "${gchoice}p")"
156-163: Add sudo/wheel: prompt/validation and empty-username guardAdd numeric validation and ensure a valid username before usermod.
- read -p "Enter the existing username: " choice - username=$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p") - admin_group="$(getent group sudo >/dev/null 2>&1 && echo sudo || echo wheel)" - usermod -aG "$admin_group" "$username" - echo "$username added to $admin_group group." + read -r -p "Select the existing user NUMBER: " choice + [[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; } + username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")" + if [[ -n "${username:-}" ]]; then + admin_group="$(getent group sudo >/dev/null 2>&1 && echo sudo || echo wheel)" + usermod -aG "$admin_group" "$username" && echo "$username added to $admin_group group." + else + echo "Invalid selection." + fi
🧹 Nitpick comments (3)
day02/pam-main.sh (3)
9-9: Remove unused color variable WHITEIt’s defined but never used. Drop it to avoid noise.
-WHITE='\033[1;37m'
142-147: Enable login: match prompt wording with behaviorMinor: the prompt should say NUMBER to align with selection style.
- read -rp "Select the existing user: " choice + read -rp "Select the existing user NUMBER: " choice
52-180: Prefer NSS-aware enumeration (getent) over parsing /etc/passwd directlyIf the system uses LDAP/SSSD, parsing /etc/passwd may miss users. Consider getent passwd and filtering by UID. Applies to all user lists.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
day02/pam-main.sh(1 hunks)
🧰 Additional context used
🪛 Shellcheck (0.10.0)
day02/pam-main.sh
[error] 1-1: Use #!, not just #, for the shebang.
(SC1113)
[warning] 9-9: WHITE appears unused. Verify use (or export if used externally).
(SC2034)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (5)
day02/pam-main.sh (5)
13-19: Run root check before banner and print errors to stderrFail fast before UI output; send the error to stderr.
-echo "------------------------------------------------------" -echo -e "=======\033[45m Welcome to Login Management System \033[0m=======" -echo "------------------------------------------------------" -if [[ $EUID -ne 0 ]]; then - echo "This script must be run as root (sudo)." - exit 1 -fi +if [[ $EUID -ne 0 ]]; then + echo "This script must be run as root (sudo)." >&2 + exit 1 +fi +echo "------------------------------------------------------" +echo -e "=======\033[45m Welcome to Login Management System \033[0m=======" +echo "------------------------------------------------------"
1-1: Fix malformed shebang and enable strict modeCurrent first line won’t invoke Bash. Add a valid shebang and safe Bash options early.
Apply:
-#/bin/bash +#!/usr/bin/env bash +set -Eeuo pipefail +IFS=$'\n\t'
33-51: Don’t exit the menu when user exists; use continueUsing break here quits the main loop.
- echo "User '$username' already exists."; echo "-----------------------------------------------"; unset username; break + echo "User '$username' already exists."; echo "-----------------------------------------------"; unset username; continue
157-165: Fix prompt/validation for sudo group additionPrompt asks for username but code expects a number; also missing numeric validation and empty check.
-awk -F: '$3 >= 1000 {print $1}' /etc/passwd | nl -w1 -s". " #Filtering only normal users -read -p "Enter the existing username: " choice -username=$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p") +awk -F: '$3 >= 1000 {print $1}' /etc/passwd | nl -w1 -s". " +read -r -p "Select the existing user NUMBER: " choice +[[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; } +username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")" +[[ -n "${username:-}" ]] || { echo "Invalid selection."; continue; } admin_group="$(getent group sudo >/dev/null 2>&1 && echo sudo || echo wheel)" usermod -aG "$admin_group" "$username" echo "$username added to $admin_group group."
81-90: Fix validation bug and unify group source
- gchoice is never validated (copy/paste uses $choice again).
- You list groups via getent but resolve from /etc/group; indexes can diverge.
- getent group | awk -F: '$3 >= 1000 {print $1}' | nl -w1 -s". " + getent group | awk -F: '$3 >= 1000 {print $1}' | nl -w1 -s". " read -p "Select the existing user NUMBER: " choice [[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; } read -p "Select the group NUMBER to be added: " gchoice - [[ "$choice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; } + [[ "$gchoice" =~ ^[0-9]+$ ]] || { echo "Invalid selection."; continue; } -username=$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p") -grpname=$(awk -F: '$3 >= 1000 {print $1}' /etc/group | sed -n "${gchoice}p") +username="$(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sed -n "${choice}p")" +grpname="$(getent group | awk -F: '$3 >= 1000 {print $1}' | sed -n "${gchoice}p")" - if [[ -n "${username}" && -n "${grpname}" ]]; then + if [[ -n "${username:-}" && -n "${grpname:-}" ]]; then
🧹 Nitpick comments (3)
day02/pam-main.sh (3)
9-9: Remove unused color variable WHITEIt’s defined but never used (SC2034).
-WHITE='\033[1;37m'
129-133: Add robust nologin fallbackIf nologin isn’t available, fall back to /bin/false.
- nologin_path="$(command -v nologin || echo /sbin/nologin)" + nologin_path="$(command -v nologin || { [[ -x /usr/sbin/nologin ]] && echo /usr/sbin/nologin || echo /bin/false; })"
144-146: Prompt consistency: ask for NUMBER explicitlyAligns with other menu prompts.
- read -rp "Select the existing user: " choice + read -rp "Select the existing user NUMBER: " choice
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
day02/pam-main.sh(1 hunks)
🧰 Additional context used
🪛 Shellcheck (0.10.0)
day02/pam-main.sh
[error] 1-1: Use #!, not just #, for the shebang.
(SC1113)
[warning] 9-9: WHITE appears unused. Verify use (or export if used externally).
(SC2034)
🔇 Additional comments (4)
day02/pam-main.sh (4)
52-76: User deletion flow looks solidNumeric validation, self-deletion guard with SUDO_USER fallback, confirm, and userdel -r are correct.
100-121: Shell toggle logic is consistent and safeGood use of getent and usermod -s with clear messages.
170-179: Group creation flow looks goodExistence check + groupadd with clear messages.
180-200: Backup flow is well-hardenedValidates user selection and directory, timestamps the archive, and quotes paths.
Hi Shubham,
As mentioned in the project #1, Shell Script for User Management and Backup in Linux. I have completed the same.
File name is - pam-main.sh under day02
It consists of:
Also added comments wherever possible to give appropriate explanation. please review and let me know if any changes.
Summary by CodeRabbit
New Features
Chores
Bug Fixes