I have a script that prompts for the user to enter a 3 letter code. I need to convert that code to a number that corresponds to a=01, b=02....etc for the first two letters of that code.
For example the user enters ABC for $SITECODE I need to take the A&B and convert it to 0102 and store it to a new variable.
#!/bin/bash
# enable logging
exec 3>&1 4>&2
trap 'exec 2>&4 1>&3' 0 1 2 3
exec 1>/var/log/ULFirstBoot.log 2>&1
###################################### global variables ######################################################
# top level domain
tld="somedomain.com"
# grabs the serial number for ComputerName
serial=`/usr/sbin/system_profiler SPHardwareDataType | /usr/bin/awk '/Serial\ Number\ \(system\)/ {print $NF}'`
# Cocoadialog location
CD="/Users/Shared/cocoaDialog.app/Contents/MacOS/cocoaDialog"
################################################### Begin Define Functions ####################################################
userinput () # Function will promt for Username,SItecode, and Region using Cocoadialog
{
# Prompt for username
rv=($($CD inputbox --title "User Name" --no-newline --informative-text "Please Enter the Users Employee ID" --icon "user" --button1 "NEXT" --button2 "Cancel"))
USERNAME=${rv[1]}
if [ "$rv" == "1" ]; then
echo "`date` User clicked Next"
echo "`date` Username set to ${USERNAME}"
elif [ "$rv" == "2" ]; then
echo "`date` User Canceled"
exit
fi
# Dialog to enter the User name and the create $SITECODE variable
rv=($($CD inputbox --title "SiteCode" --no-newline --informative-text "Enter Site Code" --icon "globe" --button1 "NEXT" --button2 "Cancel"))
SITECODE=${rv[1]} #truncate leading 1 from username input
if [ "$rv" == "1" ]; then
echo "`date` User clicked Next"
echo "`date` Sitecode set to ${SITECODE}"
elif [ "$rv" == "2" ]; then
echo "`date` User Canceled"
exit
fi
# Dialog to enter the Password and the create $REGION variable
rv=($($CD dropdown --title "REGION" --text "Choose Region" --no-newline --icon "globe" --items NA EULA AP --button1 "OK" --button2 "Cancel"))
item=${rv[1]}
if [[ "$rv" == "1" ]]
then echo "`date` User clicked OK"
elif [[ "$rv" == "2" ]]
then echo "`date` User Canceled"
exit
fi
if [ "$item" == "0" ]; then
REGION="NA"
echo "`date` Region set to NA"
elif [ "$item" == "1" ]; then
REGION="EULA"
echo "`date` Region set to EULA"
elif [ "$item" == "2" ]; then
REGION="AP"
echo "`date` Region Set to AP"
fi
# Confirm that settings are correct
rv=($($CD msgbox --text "Verify settings are correct" --no-newline --informative-text "USER-$USERNAME REGION-$REGION, SITE CODE-$SITECODE" --button1 "Yes" --button2 "Cancel"))
if [[ "$rv" == "1" ]]
then echo "`date` User clicked OK"
elif [[ "$rv" == "2" ]]
then echo "`date` User Canceled"
exit
fi
}
# Sets computername based
setname ()
{
ComputerName=$SITECODE$serial
/usr/sbin/scutil --set ComputerName $SITECODE$serial
echo "`date` Computer Name Set to" $(/usr/sbin/scutil --get ComputerName)
/usr/sbin/scutil --set LocalHostName $SITECODE$serial
echo "`date` LocalHostname set to" $(/usr/sbin/scutil --get LocalHostName)
/usr/sbin/scutil --set HostName $SITECODE$serial.$tld
echo "`date` Hostname set to" $(/usr/sbin/scutil --get HostName)
}
adbind ()
{
OU="ou=Computers,ou=${SITECODE}Win7,ou=$REGION,dc=global,dc=ul,dc=com"
echo "`date` OU will be set to $OU"
dsconfigad -add "global.ul.com" -username "user" -password "password" -ou "$OU"
dsconfigad -mobile "enable" -mobileconfirm "disable" -groups "Domain Admins, ADMIN.UL.LAPTOPADMINS"
}
# Checks if machine is succesfully bound to AD before proceeding
adcheck ()
{
until [ "${check4AD}" = "Active Directory" ]; do
check4AD=`/usr/bin/dscl localhost -list . | grep "Active Directory"`
sleep 5s
done
}
adduser () # creates mobile user account based on userinput function
{
# create mobile user account and home directory at /Users/username
/System/Library/CoreServices/ManagedClient.app/Contents/Resources/createmobileaccount -n $USERNAME -h /Users/$USERNAME
# Add newly created user to local admins group
dscl . -append /Groups/admin GroupMembership $USERNAME
# set login window to show username and password promts not a list of users
defaults write /Library/Preferences/com.apple.loginwindow SHOWFULLNAME 1
}
setADMPass ()
{
parsed1=${SITECODE:0:1}
parsed2=${SITECODE:1:1}
}
####################################### End define Functions ####################################################
############################################# Bgin Main Script #######################################################
userinput
setname
adbind
adcheck
adduser
echo $(dscl . -read /Groups/admin GroupMembership)
echo $(defaults 'read' /Library/Preferences/com.apple.loginwindow.plist SHOWFULLNAME)
# Reboot to apply changes
shutdown -r now "Rebooting to enable Mobile accounts"
Here's a funny way to do your encoding, abusing Bash's arithmetic:
string2code() {
# $1 is string to be converted
# return variable is string2code_ret
# $1 should consist of alphabetic ascii characters, otherwise return 1
# Each character is converted to its position in alphabet:
# a=01, b=02, ..., z=26
# case is ignored
local string=$1
[[ $string = +([[:ascii:]]) ]] || return 1
[[ $string = +([[:alpha:]]) ]] || return 1
string2code_ret=
while [[ $string ]]; do
printf -v string2code_ret '%s%02d' "$string2code_ret" "$((36#${string::1}-9))"
string=${string:1}
done
}
Try it:
$ string2code abc; echo "$string2code_ret"
010203
$ string2code ABC; echo "$string2code_ret"
010203
The magic happens here:
$((36#${string::1}-9))
The term 36# tells Bash that the following number is expressed in radix 36. In this case, Bash considers the characters 0, 1, ..., 9, a, b, c, ..., z (ignoring case). The term ${string:1} expands to the first character of string.
I found the answer thanks for all your help!
setADMPass ()
{
alower=abcdefghijklmnopqrstuvwxyz
site=$(echo $SITECODE | tr '[:upper:]' '[:lower:]')
parsed1=${site:0:1}
parsed2=${site:1:1}
tmp1=${alower%%$parsed1*} # Remove the search string and everything after it
ch1=$(( ${#tmp1} + 1 ))
tmp2=${alower%%$parsed2*} # Remove the search string and everything after it
ch2=$(( ${#tmp2} + 1 ))
if [[ $ch1 -lt 10 ]]; then
#statements
ch1=0$ch1
fi
if [[ $ch2 -lt 10 ]]; then
#statements
ch2=0$ch2
fi
passpre=$ch1$ch2
}
see if this helps! BASH 4+. If you find any issues, that'd be your homework.
#!/bin/bash
declare -A koba
i=1
for vi in {a..z};do koba=(["$vi"]="0${i}"); ((i++)); done
for vi in {A..Z};do koba=(["$vi"]="0${i}"); ((i++)); done
echo -en "\nEnter a word: "; read w; w="$( echo $w | sed "s/\(.\)/\1 /g" | cut -d' ' -f1,2)";
new_var="$(for ch in $w; do echo -n "${koba["${ch}"]}"; done)";
echo $new_var;
Related
I have been trying to implement a code that makes a predefined user created, be put into a specific groups (first 5 in MyMembers, next 5 in MyGroup, and last 5 to MyMinions), but I always got lost in coding it.
So far this is my code in creating predefined user.
#!/bin/bash
#This script adds a user with a hidden password to your #system.
ans=yes
while [[ "$ans" = yes ]] ;
do
if [ $(id -u) -eq 0 ];
then
read -p "Enter username: " username
read -s -p "Enter password: " password
egrep "^$username" /etc/passwd >/dev/null
if [ $? -eq 0 ];
then
echo "$username already exists!"
exit 1
else
pass=$(perl -e 'print crypt ($ARGV[0], "password")' $password)
useradd -m -p $pass $username
[ $? -eq 0 ] && echo -e "\nUser has been added to your system!" || echo "\nFailed to add the user!"
fi
else
echo "Only root may add a user to the system"
exit 2
fi
echo -e "\nDo you still want to add more users?. \nType yes to continue adding. \nType yes or any key to exit"
read ans
done
exit
In order to simplicate the process of creating a new user in my company's NIS server, I wrote the following scripts:
#!/bin/bash
# This script will simplicate NIS user management.
# You will not be able to change password or delete users peeradmin and root through this script.
# Written by Itai Ganot 2014.
# Variables
USER=$1
GREP="/bin/grep"
PASSWDFILE="/etc/passwd"
YPPASSWD="/usr/bin/yppasswd"
USERDEL="/usr/sbin/userdel"
USERADD="/usr/sbin/useradd"
PASSWD="/usr/bin/passwd"
YPCAT="/usr/bin/ypcat passwd.byname"
# Functions
function usage {
echo -e "Usage: $0 <username to manage>"
}
function updatenis {
echo -e "\e[36m #===# Uptdating NIS database... \e[0m"
cd /var/yp && make
}
# Script
if [ -z "$USER" ]; then
usage
exit 1
fi
if [ "$(id -u)" != "0" ]; then
echo -e "Run as root!"
exit 1
fi
"$GREP" -q "$USER" "$PASSWDFILE"
if [ "$?" = "0" ]; then
echo -e "\e[36m #===# User already exists \e[0m"
echo -e "\e[36m #===# How would you like to continue? \e[0m"
USERID=$(id -u $USER)
select CHOICE in 'Change user password' 'Remove user' 'View user' 'Exit'; do
case $CHOICE in
"Change user password")
if [[ "$USER" = "peeradmin" || "$USER" = "root" ]]; then # Defense against changing root or peeradmin password
echo -e "\e[36m #===# User $USER should never be edited! \e[0m"
exit 1
fi
echo -e "\e[36m #===# Provide root password for NIS server... \e[0m"
"$YPPASSWD" "$USER"
break
;;
"Remove user")
if [[ "$USER" = "peeradmin" || "$USER" = "root" ]]; then # Defense against deletion of user root or peeradmin.
echo -e "\e[36m #===# User $USER should never be edited! \e[0m"
exit 1
fi
read -r -p "Remove home directory and mail? [y/n] " ANSWER1
if [[ "$ANSWER1" = [Yy] ]]; then
"$USERDEL" -r "$USER"
updatenis
echo -e "\e[36m #===# User $USER has been deleted along with the user's home folder and mail \e[0m"
break
else
"$USERDEL" "$USER"
echo -e "\e[36m #===# User $USER has been deleted \e[0m"
updatenis
break
fi
;;
"View user")
echo -e "\e[36m #===# Displaying user $USER \e[0m"
$YPCAT | $GREP "$USER"
break
;;
"Exit")
echo -e "\e[36m #===# Exiting, No changes done. \e[0m"
exit 0
;;
esac
done
else
read -r -p "User doesn't exist, would you like to add it? [y/n] " ANSWER2
if [[ "$ANSWER2" = [Yy] ]]; then
echo -e "\e[36m #===# Collecting required information... \e[0m"
sleep 2
LASTUID=$(tail -n 1 $PASSWDFILE | awk -F: '{print $3}')
NEXTUID=$(( LASTUID + 1 ))
$USERADD -g users $USER -u $NEXTUID
echo -e "\e[36m #===# Set password for the new user \e[0m"
$PASSWD $USER
updatenis
read -r -p "Would you like to test the creation of the user? [y/n] " ANSWER3
if [[ "$ANSWER3" = [Yy] ]]; then
$YPCAT | $GREP "$USER"
if [ "$?" = "0" ]; then
echo -e "\e[36m #===# User $USER created successfully! \e[0m"
fi
fi
elif [[ "$ANSWER2" = [Nn] ]]; then
echo -e "\e[36m #===# Exiting, no changes done. \e[0m"
exit 0
fi
fi
I want to make the script public so I'll be able to share it with some communities, however I'm having a hard time to get some specific thing done.
I want to define a new variable called: PROTECTEDUSERS and assign one or more usernames to it.
Example:
PROTECTEDUSERS="root peeradmin"
Then, In the relevant line:
if [[ "$USER" = "peeradmin" || "$USER" = "root" ]];
I want the line to include the newly created variable.
I've tried this:
if [[ "*$USER*" =~ "$PROTECTEDUSERS" ]]; then...
But it doesn't work, is that even a possible thing to do? I believe it is just don't know how to do it, please assist.
Thanks in advance
if [[ "$PROTECTEDUSERS" =~ $USER ]]; then
Update to not match substings like "admin":
if [[ "$PROTECTEDUSERS" =~ (^| )$USER($| ) ]]; then
You are using glob in reverse direction, use this condition with == in bash:
if [[ "$PROTECTEDUSERS" == *"$USER"* ]]; then...
glob pattern is only supported on RHS of comparison.
Default_Dir=/export/home/cwatts/test
Default_Log=DB.Audit
echo "Please, enter your Fullname [ENTER]:"
read fname
if [ -z "$fname" ]; then
echo "Please enter a value!"
exit 0
else
echo "Please, enter the Database name [ENTER]:"
read dbname
if [ -z "$dbname" ]; then
echo "Please enter a value!"
else
echo "Please, enter a brief Description [ENTER]:"
read desc
if [ -z "$desc" ]; then
echo "Please enter a value!"
fi
fi
fi
if [ ! -d $Default_Dir ]; then
echo "directory doesn't exit, it will be created"
mkdir $Default_Dir
fi
echo `date -u` $dbname $fname $desc >> $Default_Dir/$Default_Log
exit
You can do something like this:
while [ -z "${value-}" ]
do
echo "Please, enter your Fullname [ENTER]:"
read value
done
Expanding somewhat on l0b0's answer and refactoring for legibility and idiomatic expression:
nonempty () {
test -n "$1" && return 0
echo "Please enter a value" >&2
return 1
}
while true; do
read -p "Please, enter your Fullname [ENTER]: " fname
nonempty "$fname" || continue
read -p "Please, enter the Database name [ENTER]: " dbname
nonempty "$dbname" || continue
read -p "Please, enter a brief Description [ENTER]:" desc
nonempty "$desc" || continue
break
done
date -u +"%c $dbname $fname $desc" >> $Default_Dir/$Default_Log
(The hack to put the string you want to echo in the format string of date will break if any of the values could contain a percent sign.)
If you are okay with the slightly dubious practice of having a function define global variables for you, the code duplication can still be reduced significantly.
accept () {
read -p "$2 [ENTER]: " "$1"
test -n "${!1}" && return 0
echo "Please enter a value" >&2
return 1
}
while true; do
accept fname "Please, enter your Fullname" || continue
accept dbname "Please, enter the Database name" || continue
accept desc "Please, enter a brief Description" || continue
break
done
The indirect variable reference ${!var} is a Bashism, and not portable to other shells.
username=$1
freq=$2
checkuser()
{
if who grep "$1"
then
sleep 60
fi
}
if [ -n "$1" ]
then
echo "Enter username"
read username
checkuser
echo -e "$1 is logged on \a"
echo -e "$1 logged in at `date`">>LOG
checkuser
else
echo "User is not logged on"
fi
I need to integrate a second argument into my code which allows for the user to specify after what time should the script check to see who is logged in. I have it set to 60 seconds currently and this needs to be the default frequency. I tried to use another function but to no avail. I thought of something like this...
if [ "$2" -ne 0 ]
then
freq=$2
else
freq=60
Thanks William for that was very helpful!! I changed the code a bit and came up with this. I now need to add a 3rd argument "X" which when selected just sends a message to the LOGFILE and not to the screen. I made an attempt but not doing as intended.
username=$1
freq=${2:-10}
X=$3
checkuser()
{
whoami|grep "$1";
}
while checkuser "$username"
do
echo -e "$1 is logged on \a"
echo "$1 logged in at `date`">>LOGFILE
sleep $freq
exit 0
done
echo "User is not logged in"
if [ "$3" -ne 1 ]
then
echo "$1 logged in at `date`"LOGFILE
fi
username=$1
freq=${2:-60} # Set a default frequency
checkuser(){ who | grep -q "$1"; }
while ! checkuser "$username"; do
echo "User is not logged on"
sleep $freq
done
echo "$1 is logged on"
Also note that you can simplify the setting of username:
username=${1:-$( echo "Enter username: "; read u; echo $u; )}
echo 'Enter id'
read id
res=`who | grep "$id" | wc -l`
if [ $res -eq 0 ]
then
echo 'user is not logged in'
else
echo 'user is logged in'
fi
A simple shell script that takes the username as input and determines whether the user is currently logged in.
if [[ $# -eq 0 ]]; then
echo "Usage: " $0 "username"
exit 1
fi
result="$(who | grep $1 | wc -l)"
if [[ $result -gt 0 ]]; then
echo "$1 is currently logged in"
else
echo "$1 is not logged in"
fi
exit 0
I have the script listed below that I can't seem to get the issue worked out of. I'm trying to make an interactive login script for a UNIX class that I'm in. I'm basically building out a command to pass into useradd. The command that I make when passed into the command line (while adding sudo) works as expected, but when I try to run it from my script (which is generating the text that I copy/paste into the command line) it gives me some errors... At this point I'm at a loss for what to try next to resolve the issue.
ERROR:
useradd -m --user-group jaredm2 #command that is attempting to run...
useradd: invalid option -- ' '
Usage: useradd [options] LOGIN
....rest of useradd error text....
SCRIPT:
#!/bin/bash
#Add a new user
FINALCOMMAND="-m"
#import useradd defaults...
. /etc/default/useradd
#Check if running as root
if [ "$(id -u)" != "0" ]; then
echo "This script must be ran as root"
exit 1
fi
#Get the new users Name
#echo -n "Please enter the users First and Last Name and press [ENTER]: "
#read Name
#Get the new users username
echo "The username must be 4-20 characters."
echo -n "Please enter the users requested username and press [ENTER]: "
read USERNAME
while [ $(grep -c "^${USERNAME}:" /etc/passwd) -ge 1 ] || [ ${#USERNAME} -le 3 ] || [ ${#USERNAME} -ge 21 ]
do
echo " "
echo "Error: Username is in use or invalid. Please select a different username."
echo " "
echo -n "Please enter the users requested username and press [ENTER]: "
read USERNAME
done #USERNAME will be valid from this point
#ASK about the default shell now
echo -n "Enter the new shell if you would like one (currently $SHELL) or leave blank for the default and press [ENTER]: "
read tempSHELL
if [ ${#tempSHELL} -ge 1 ]; then
SHELL="$tempSHELL"
FINALCOMMAND="$FINALCOMMAND ""-s $SHELL"
fi
#ASK about a different primary group
echo "Would you like to enter a non-default primary user group? Defaults to creating a new group that matches the username"
echo "Enter a new Primary Group or leave blank for the default and press [ENTER]: "
read newPrimaryGroup
if [ ${#newPrimaryGroup} -eq 0 ]; then
FINALCOMMAND="$FINALCOMMAND --user-group"
else
if [ $(grep -c "^${newPrimaryGroup}" /etc/group) -ge 1 ]; then
FINALCOMMAND="$FINALCOMMAND -g $newPrimaryGroup"
else
echo "Invalid group specified reverting to default!"
FINALCOMMAND="$FINALCOMMAND --user-group"
fi
fi
useradd -m --user-group jaredm2
#ASK about additional groups
echo "Would you like the new user to be a part of any additional groups? Leave blank if no additional groups are needed or enter additional groups in the format of GROUP1,GROUP2,... (NO SPACES) and press [ENTER]: "
read extraGroups
#remove spaces if the user entered any
extraGroups="${extraGroups//[[:space:]]}"
FINALEXTRAGROUPS=""
IFS=","
for g in $extraGroups
do
if [ $(grep -c "^${g}" /etc/group) -ge 1 ]; then
FINALEXTRAGROUPS="$FINALEXTRAGROUPS,$g"
else
echo "$g is invalid user will not be added..."
fi
done
FINALEXTRAGROUPS=$(echo "$FINALEXTRAGROUPS" | tail -c +2)
if [ ${#FINALEXTRAGROUPS} -ge 1 ]; then
FINALCOMMAND="$FINALCOMMAND -G $FINALEXTRAGROUPS"
fi
#ASK about the home directory
echo "Would you like to enter a new home directory for the user? Leave blank to use the default of $HOME/$USERNAME or enter your own and press [ENTER]: "
read NEWHOME
if [ ${#NEWHOME} -ge 1 ]; then
FINALCOMMAND="$FINALCOMMAND -d $NEWHOME"
fi
#ADD the username to the command
FINALCOMMAND=`echo "$FINALCOMMAND $USERNAME" | sed 's/ *$//g' | sed 's/^ *//g'`
echo "useradd $FINALCOMMAND"
#PASSCOMMAND="sudo passwd $USERNAME"
#ADD THE USER
`useradd $FINALCOMMAND`
`passwd $USERNAME`
`chfn $USERNAME`
UPDATE: ADDED DEBUG CONTENT
+ '[' 0 -ge 1 ']'
++ sed 's/^ *//g'
++ sed 's/ *$//g'
++ echo '/usr/sbin/useradd -m -U JaredM'
+ FINALCOMMAND='/usr/sbin/useradd -m -U JaredM'
++ '/usr/sbin/useradd -m -U JaredM'
./addnewuser.sh: line 89: /usr/sbin/useradd -m -U JaredM: No such file or directory
By using arrays you could prevent IFS related errors in the command-line and it's a lot cleaner. This one's already tested. I made some clean-ups to the code as well.
#!/bin/bash
#Add a new user
FINALCOMMAND=("-m")
#Import useradd defaults...
. /etc/default/useradd
#Check if running as root
if [ "$(id -u)" != "0" ]; then
echo "This script must be ran as root"
exit 1
fi
#Get the new users Name
#echo -n "Please enter the users First and Last Name and press [ENTER]: "
#read Name
#Get the new users username
echo "The username must be 4-20 characters."
echo -n "Please enter the users requested username and press [ENTER]: "
read USERNAME
while [ $(grep -c "^${USERNAME}:" /etc/passwd) -ge 1 ] || [ ${#USERNAME} -le 3 ] || [ ${#USERNAME} -ge 21 ]; do
echo " "
echo "Error: Username is in use or invalid. Please select a different username."
echo " "
echo -n "Please enter the users requested username and press [ENTER]: "
read USERNAME
done #USERNAME will be valid from this point
#ASK about the default shell now
echo -n "Enter the new shell if you would like one (currently $SHELL) or leave blank for the default and press [ENTER]: "
read tempSHELL
if [ ${#tempSHELL} -ge 1 ]; then
SHELL="$tempSHELL"
FINALCOMMAND=("${FINALCOMMAND[#]}" "-s" "$SHELL")
fi
#ASK about a different primary group
echo "Would you like to enter a non-default primary user group? Defaults to creating a new group that matches the username"
echo -n "Enter a new Primary Group or leave blank for the default and press [ENTER]: "
read newPrimaryGroup
if [ ${#newPrimaryGroup} -eq 0 ]; then
FINALCOMMAND=("${FINALCOMMAND[#]}" "--user-group")
else
if [ $(grep -c "^${newPrimaryGroup}" /etc/group) -ge 1 ]; then
FINALCOMMAND=("${FINALCOMMAND[#]}" "-g" "$newPrimaryGroup")
else
echo "Invalid group specified reverting to default!"
FINALCOMMAND=("${FINALCOMMAND[#]}" "--user-group")
fi
fi
#ASK about additional groups
echo -n "Would you like the new user to be a part of any additional groups? Leave blank if no additional groups are needed or enter additional groups in the format of GROUP1,GROUP2,... (NO SPACES) and press [ENTER]: "
read extraGroups
#remove spaces if the user entered any
extraGroups="${extraGroups//[[:space:]]}"
FINALEXTRAGROUPS=''
IFS=, read -a TEMP <<< "$extraGroups"
for g in "${TEMP[#]}"; do
if [ $(grep -c "^${g}" /etc/group) -ge 1 ]; then
FINALEXTRAGROUPS="$FINALEXTRAGROUPS,$g"
else
echo "$g is invalid user will not be added..."
fi
done
if [ ${#FINALEXTRAGROUPS[#]} -ge 1 ]; then
FINALCOMMAND=("${FINALCOMMAND[#]}" "-G" "${FINALEXTRAGROUPS:1}")
fi
#ASK about the home directory
echo -n "Would you like to enter a new home directory for the user? Leave blank to use the default of $HOME/$USERNAME or enter your own and press [ENTER]: "
read NEWHOME
if [ ${#NEWHOME} -ge 1 ]; then
FINALCOMMAND=("${FINALCOMMAND[#]}" "-d" "$NEWHOME")
fi
#ADD the username to the command
FINALCOMMAND=("${FINALCOMMAND[#]}" "$USERNAME")
#PASSCOMMAND="sudo passwd $USERNAME"
#ADD THE USER
echo "useradd ${FINALCOMMAND[#]}"
useradd "${FINALCOMMAND[#]}"
passwd "$USERNAME"
chfn "$USERNAME"
Note: In newer versions of bash you could just use += to append a value to an array e.g. ARRAY+=("value")
Also by my additional preferences I would improve the code further this way, but that's not the best of it yet:
#!/bin/bash
shopt -s extglob
# Check if running as root.
if [[ "$(id -u)" != 0 ]]; then
echo "This script must be ran as root."
exit 1
fi
# Initialize useradd command variable.
USERADDCOMMAND=("useradd" "-m")
# Import useradd defaults.
. /etc/default/useradd
# Get the new user's name.
#echo -n "Please enter the users First and Last Name and press [ENTER]: "
#read NAME
# Get the new users username.
echo "The username must be 4-20 characters."
while :; do
read -p "Please enter the user's requested username and press [ENTER]: " USERNAME
[[ ${#USERNAME} -ge 4 && ${#USERNAME} -le 20 && $USERNAME == +([[:alpha:]])*([[:alnum:]_-]) ]] || {
echo "Error: Username is invalid. Please enter a different username."
continue
}
[[ $(grep -c "^${USERNAME}:" /etc/passwd) -ge 1 ]] && {
echo "Error: Username is in use. Please enter a different username."
continue
}
break
done
# Ask about the default shell.
read -p "Enter the new shell if you would like one (currently $SHELL) or leave blank for the default and press [ENTER]: " SHELL_
if [[ ${#SHELL_} -ge 1 ]]; then
USERADDCOMMAND=("${USERADDCOMMAND[#]}" "-s" "$SHELL_")
else
# We use this if we really are to use SHELL specified in $SHELL but it still needs further workarounds like checking if $SHELL is valid. Those could be easily done but it depends if this one's really necessary.
#USERADDCOMMAND=("${USERADDCOMMAND[#]}" "-s" "$SHELL")
:
fi
# Ask about a different primary group.
echo "Would you like to enter a non-default primary user group? Defaults to creating a new group that matches the username."
echo -n "Enter a new Primary Group or leave blank for the default and press [ENTER]: "
read NEWPRIMARYGROUP
if [[ ${#NEWPRIMARYGROUP} -eq 0 ]]; then
USERADDCOMMAND=("${USERADDCOMMAND[#]}" "--user-group")
else
if [[ $(grep -c "^${NEWPRIMARYGROUP}" /etc/group) -ge 1 ]]; then
USERADDCOMMAND=("${USERADDCOMMAND[#]}" "-g" "$NEWPRIMARYGROUP")
else
echo "Invalid group specified reverting to default!"
USERADDCOMMAND=("${USERADDCOMMAND[#]}" "--user-group")
fi
fi
# Ask about additional groups.
echo -n "Would you like the new user to be a part of any additional groups? Leave blank if no additional groups are needed or enter additional groups in the format of GROUP1,GROUP2,... (NO SPACES) and press [ENTER]: "
read EXTRAGROUPS
# Remove spaces if the user entered any.
EXTRAGROUPS="${EXTRAGROUPS//[[:space:]]}"
FINALEXTRAGROUPS=''
IFS=, read -a TEMP <<< "$EXTRAGROUPS"
for G in "${TEMP[#]}"; do
if [[ $(grep -c "^${g}" /etc/group) -ge 1 ]]; then
FINALEXTRAGROUPS="$FINALEXTRAGROUPS,$G"
else
echo "$G is an invalid user and will not be added."
fi
done
if [[ ${#FINALEXTRAGROUPS[#]} -ge 1 ]]; then
USERADDCOMMAND=("${USERADDCOMMAND[#]}" "-G" "${FINALEXTRAGROUPS:1}")
fi
# Ask about the home directory
read -p "Would you like to enter a new home directory for the user? Leave blank to use the default of $HOME/$USERNAME or enter your own and press [ENTER]: " NEWHOME
if [[ ${#NEWHOME} -ge 1 ]]; then
USERADDCOMMAND=("${USERADDCOMMAND[#]}" "-d" "$NEWHOME")
fi
# Add the username to the command
USERADDCOMMAND=("${USERADDCOMMAND[#]}" "$USERNAME")
# Add THE USER
echo "> ${USERADDCOMMAND[*]}"
"${USERADDCOMMAND[#]}"
echo "> passwd $USERNAME"
passwd "$USERNAME"
echo "> chfn $USERNAME"
chfn "$USERNAME" # -f "$NAME"
If the man -s8 useradd does not mention --user-group option available to use, then -U will not work. There's still another solution worth trying:
The default behavior (if the -g, -N, and -U options are not specified)
is defined by the USERGROUPS_ENAB variable in /etc/login.defs.
Another way is, you have to chain the useradd command with a groupadd command with the same username supplied as parameters to both the commands.
EDIT:
This must work. First create the group and then create the user and add this new user to the group. Since, you are doing this in a script this should do the job very well.
Do this:
groupadd jaredm2
useradd -m -g jaredm2 jaredm2
Instead of this:
useradd -m --user-group jaredm2
Note that certain other programs which would've been installed in your OS, may have changed your binary or access to it or even created an alias for it. Your which output suggests that it is linked to the useradd binary in bin directory, precisely where it should be.
So I guess:
the binary might have been changed or replaced by a process, by package installers or something else
there's some mismatch between the binary version and the man page version(most likely if you have upgraded your OS improperly, at some point of time)
I think, the only solutions would be using the above pair of commands or changing the useradd binary you are using manually.
The problem is caused by your script you made the use magic quotes `...` to execute your shell commands.
These quotes should only be used if you want to store the return of a command in a variable:
example the instruction below:
FINALCOMMAND=`echo "$FINALCOMMAND $USERNAME" | sed 's/ *$//g' | sed 's/^ *//g'`
Otherwise it is not necessary to use this quote and they can produce bugs like yours.
you can put in your script:
useradd $FINALCOMMAND
passwd $USERNAME
chfn $USERNAME
instead of:
`useradd $FINALCOMMAND`
`passwd $USERNAME`
`chfn $USERNAME`
Judging from your update with debug content, it seems like what you are doing is different from the script you posted.
Anyway, from the debug output, I suspect you're trying to run the adduser command using double quotes
"$FINALCOMMAND"
or maybe enclosed in backticks too, as that seems to be the only situation that triggers the "No such file or directory" error message.
Getting rid of the double quotes should fix the problem.
p/s: Don't use command substitution (``) unless you're actually using the output (e.g. for testing or assigning to variables), or else something like this might happen
$ `echo Just saying hi`
Just: command not found
I fixed the bug in your script, simply remove the line IFS=","
It is a misuse of the environment variable IFS (Internal Field Separator)
The script becomes:
#!/bin/bash
#Add a new user
FINALCOMMAND="-m"
#import useradd defaults...
. /etc/default/useradd
#Check if running as root
if [ "$(id -u)" != "0" ]; then
echo "This script must be ran as root"
exit 1
fi
#Get the new users Name
#echo -n "Please enter the users First and Last Name and press [ENTER]: "
#read Name
#Get the new users username
echo "The username must be 4-20 characters."
echo -n "Please enter the users requested username and press [ENTER]: "
read USERNAME
while [ $(grep -c "^${USERNAME}:" /etc/passwd) -ge 1 ] || [ ${#USERNAME} -le 3 ] || [ ${#USERNAME} -ge 21 ]
do
echo " "
echo "Error: Username is in use or invalid. Please select a different username."
echo " "
echo -n "Please enter the users requested username and press [ENTER]: "
read USERNAME
done #USERNAME will be valid from this point
#ASK about the default shell now
echo -n "Enter the new shell if you would like one (currently $SHELL) or leave blank for the default and press [ENTER]: "
read tempSHELL
if [ ${#tempSHELL} -ge 1 ]; then
SHELL="$tempSHELL"
FINALCOMMAND="$FINALCOMMAND ""-s $SHELL"
fi
#ASK about a different primary group
echo "Would you like to enter a non-default primary user group? Defaults to creating a new group that matches the username"
echo "Enter a new Primary Group or leave blank for the default and press [ENTER]: "
read newPrimaryGroup
if [ ${#newPrimaryGroup} -eq 0 ]; then
FINALCOMMAND="$FINALCOMMAND --user-group"
else
if [ $(grep -c "^${newPrimaryGroup}" /etc/group) -ge 1 ]; then
FINALCOMMAND="$FINALCOMMAND -g $newPrimaryGroup"
else
echo "Invalid group specified reverting to default!"
FINALCOMMAND="$FINALCOMMAND --user-group"
fi
fi
#useradd -m --user-group jaredm2
#ASK about additional groups
echo "Would you like the new user to be a part of any additional groups? Leave blank if no additional groups are needed or enter additional groups in the format of GROUP1,GROUP2,... (NO SPACES) and press [ENTER]: "
read extraGroups
#remove spaces if the user entered any
extraGroups="${extraGroups//[[:space:]]}"
FINALEXTRAGROUPS=""
#IFS=","
for g in $extraGroups
do
if [ $(grep -c "^${g}" /etc/group) -ge 1 ]; then
FINALEXTRAGROUPS="$FINALEXTRAGROUPS,$g"
else
echo "$g is invalid user will not be added..."
fi
done
FINALEXTRAGROUPS=$(echo "$FINALEXTRAGROUPS" | tail -c +2)
if [ ${#FINALEXTRAGROUPS} -ge 1 ]; then
FINALCOMMAND="$FINALCOMMAND -G $FINALEXTRAGROUPS"
fi
#ASK about the home directory
echo "Would you like to enter a new home directory for the user? Leave blank to use the default of $HOME/$USERNAME or enter your own and press [ENTER]: "
read NEWHOME
if [ ${#NEWHOME} -ge 1 ]; then
FINALCOMMAND="$FINALCOMMAND -d $NEWHOME"
fi
#ADD the username to the command
FINALCOMMAND=`echo "$FINALCOMMAND $USERNAME" | sed 's/ *$//g' | sed 's/^ *//g'`
echo "useradd $FINALCOMMAND"
#PASSCOMMAND="sudo passwd $USERNAME"
#ADD THE USER
useradd $FINALCOMMAND
passwd $USERNAME
chfn $USERNAME