Synchronize all current users in bash script using mkfifo pipe - linux

I'm creating a program written in bash script that manages users and groups. I want to reload all current users when I add or delete a user in a specific tab. I tried to use mkfifo fpipe but it only reloads all users when I restart the app. Any ideas to solve this problem? Below is the code that performs this function.
mkfifo "$fpipe"
trap "rm -f $fpipe $fts" EXIT
fpipe="OUTPUT.txt"
#getAllUsers function
function get_all_user(){
echo -e '\f' >> "$fpipe"
alluser=$(cat /etc/passwd | awk -F: '$7=="/bin/bash" {print $1"\\n"$3"\\n"$4"\\n"}' | tr -d '[:space:]' )
echo -e $alluser > "$fpipe"
}
export -f get_all_user
#get_selected_user function
function get_selected_user()
{
echo -e '\f' > "$temp"
echo "$1" > "$temp"
cat $temp
}
export -f get_selected_user
#adduser function
function run_adduser()
{
# check for this in '/etc/passwd' and '/etc/shadow'
# $2 is the username
# $3 is the password
if id "$2" &>/dev/null; then
zenity --warning \
--text="Username existed. Please enter another username."
else
useradd -m -p $(openssl passwd -1 $3) -s /bin/bash -G sudo $2
zenity --info \
--text="User added successfully."
fi
}
export -f run_adduser
# Users information tab
get_all_user
yad --plug=$KEY --tabnum=1 --width=600 --height=450 --expand-column=0 --limit=10 \
--list --select-action='#bash -c "get_selected_user %s %s %s"' --column="Username" --column="UID" --column="GID" <&3 &
exec 3>&-

Related

Bash script to remove large number of users is not running

my bash script wont run, and does not output anything past echo "Running gke old user cleanup". There is no fail message, it just doesn't run. Any suggestions?
#!/bin/bash
set -o pipefail
set -o nounset
date
echo "Running old user cleanup"
for user in $(awk -F':' '$1 ~ /^kub-[a-z0-9]{20}$/ { print $1 }' /etc/passwd); do
echo "Cleaning up '${user}'"
userdel -r "${user}"
rc=$?
if [[ $rc != 0 ]]; then
echo "Failed to cleanup '${user}': exit code: ${rc}"
else
echo "Successfully cleaned up '${user}'"
fi
done
Maybe simplify the loop.
while read user
do if userdel -r "${user}"
then echo "Successfully cleaned up '${user}'"
else echo "Failed to cleanup '${user}': exit code: '$?'"
fi
done < <( awk -F':' '$1 ~ /^gke-[a-z0-9]{20}$/ { print $1 }' /etc/passwd )
Should at least be easier to debug.
Add set -x as suggested to see what's being evaluated.

Verify account creation from text file in bash script

I am trying to output which accounts have been successfully created from a text file and which haven't. I would also like to output the number of successfully created accounts. I currently the get the following error: grep: 3: No such file or directory. The script and text file and saved in the same folder. I have use the following commands in my script.
file=users.txt
verify =grep "verify" $file |cut -f2 -d:`
cat /etc/passwd | grep $verify
echo -e "\nYou have Currently"
cat /etc/passwd | grep $verify |wc -l;
echo "users added from your Text File"
Edit:
#!/bin/bash
ROOT_UID=0 #The root user has a UID of 0
if [ "$UID" -ne "$ROOT_UID" ]; then
echo "**** You must be the root user to run this script!****"
exit
fi
clear
echo
echo "######################################################"
echo "##### Batch script to automate creation of users #####"
echo -e "######################################################\n"
while true;
do
file=notvalid
while [ $file == "notvalid" ]
do
#echo "repeat $repeat"
#echo -e "\n"
echo -n "Please enter import filename:"
read filename
echo -e "\r"
exists=0
if [ -e $filename ]; then
file=valid
while IFS=":" read firstname lastname userid password group
do
egrep -i "^$userid:" /etc/passwd &>/dev/null
if [ $? -eq 0 ]; then
exists=$((exists+1))
#echo -e "${firstname} ${lastname} already exists on the system"
#grep ${userid} /etc/passwd
aname=$( getent passwd "$userid" | cut -d: -f3)
echo "Account Exists: $aname"
euserid=$( getent passwd "$userid" | cut -d: -f1)
echo "User ID: $userid"
homedir=$( getent passwd "$userid" | cut -d: -f6)
echo "Home Directory: $homedir"
usershell=$( getent passwd "$userid" | cut -d: -f7)
echo "User Shell: $usershell"
g=$( id -Gn "$userid")
echo "Groups: $g"
echo -e "\r"
else
egrep -i "^$group:" /etc/group &>/dev/null
if [ $? -eq 1 ]; then
/usr/sbin/addgroup ${group} &>/dev/null
fi
useradd -d /home/"${userid}" -m -s /bin/bash -c \
"${firstname}${lastname}" -g "${group}" "${userid}"
echo "Creating Account: ${firstname} ${lastname}"
nuserid=$( getent passwd "$userid" | cut -d: -f1)
echo "Creating User ID: ${nuserid}"
{ echo ${password}; echo ${password}; } | sudo passwd ${userid} > /dev/null 2>&1
echo "Creating Password: ${password}"
echo "Creating Home Directory: /home/${userid}"
echo "Creating User Shell: /bin/bash"
echo -e "Assigning Group: ${group}\n"
fi
done < $filename
else
echo -e "##### CANNOT FIND OR LOCATE FILE #####"
fi
verify=`grep "verify" /home/pi/$filename | cut -f3 -d:`
echo "$verify"
count=0
for id in $verify
do grep -wo ^$id /etc/passwd && count=$((count+1))
done
echo $count users added from your text file
echo these are not added:
for id in $verify
do grep -wq ^$id /etc/passwd || echo $id
done
while true
do
echo -n "Create additional accounts [y/n]: "
read opt
if [[ $opt == "n" || $opt == "y" ]];then
break
else
echo "Invalid Input"
fi
done
if [ $opt = "n" ]; then
clear
break
else
clear
fi
done
You were almost there.
The main issue with your approach is that you try to search for multiple accounts at once with grep. The variable verify has multiple userids so you need to process it one by one.
file=users.txt
verify=`grep "verify" $file | cut -f2 -d:`
count=0
for id in $verify
do grep -wo ^$id /etc/passwd && count=$((count+1))
done
echo $count users added from your text file
echo these are not added:
for id in $verify
do grep -wq ^$id /etc/passwd || echo $id
done
The for loop will take each element in your verify variable into id and search with grep (-w matches only whole words, not fragments, ^ matches the beginning of line and -o outputs only the matching word not the whole line).
We count the number of matches in the count variable. Alternative approach to run the for loop twice and pipe the second one to wc -l as you did.
&& operator means it will increase count if the previous command found a match (the return code of grep was 0).
The next loop will not print matching ids (-q), and will echo id if grep did not found a match (the return code was not 0). This is achieved with the || operator.
One last note on iteration of a list: if the members can contain spaces (unlike userids), you should use ${verify[#]} (this is a bash-ism) instead of $verify .
And forget this: cat /etc/passwd | grep pattern, use grep pattern /etc/passwd instead.

make scripts run only one instance when a user logs in

I am trying to run a few bash scripts continually when I am logged in to my Linux Mint install. Adding them to startup applications doesnt appear to work, because they are not always running when I check. I also dont want to create multiple instances of the scripts so adding them to my .bashrc or a cronjob seems to be out. Any other suggestions?
An example script (warns me when my battery is below 30%):
#!/bin/bash
while :
do
#echo "starting script: $(date)">>battery_log
percent=$(upower -i /org/freedesktop/UPower/devices/battery_BAT0| grep -E "percentage" | grep -o '[0-9]\+')
cpu_temp=$(cat /sys/class/thermal/thermal_zone0/temp | awk '{print "deg C: "$1/1000}')
discharge=$(upower -i /org/freedesktop/UPower/devices/battery_BAT0| grep -E "state")
is_discharging=$(echo $discharge | grep -c discharging)
#echo "$percent"
#echo "$cpu_temp"
#echo hello | grep -c he
#if [echo $discharge | grep -c discharging -gt 0 ]; then
#echo "success"
#fi
#echo "$discharge"
if [ "$is_discharging" -gt 0 ]; then
echo "---discharging: $(date)">>battery_log
if [ "$percent" -lt 30 ]; then
#exec 2>>/home/king/Scripts/battery_log.txt
export DISPLAY=:0
#export XAUTHORITY=~otheruser/.Xauthority
#kdialog --msgbox "$(upower -i /org/freedesktop/UPower/devices/battery_BAT0| grep -E "state|to\ full|percentage") \n cpu temp: $(cat /sys/class/thermal/thermal_zone0/temp | awk '{print "deg C: "$1/1000}')"
kdialog --title "Low Battery" --passivepopup "$(upower -i /org/freedesktop/UPower/devices/battery_BAT0| grep -E "state|to\ full|percentage") \n cpu temp: $(cat /sys/class/thermal/thermal_zone0/temp | awk '{print "deg C: "$1/1000}')" 20
fi
fi
sleep 300 #5min
done
Before you run the script, check if an instance of your script is already running.
pgrep script.sh.
If it's already running, then you can exit, otherwise continue the script.
pgrep script.sh && exit should do the trick.

Passing csv file data into command using .sh file in linux

I want to pass my n number csv data into command "esusers useradd username -r role -p password". How can i perform this in linux machine. i Have done this window but unable to do in linux machine can anyone help me out of this. My input will contain header also.
csv file user.csv:
user1,role1,pass1
user2,role2,pass2
user3,role3,pass3
The bash script (scripts.sh) to iterate over the csv file:
#!/bin/bash
# Check parameters
if [ "$#" -ne 1 ]; then
>&2 echo "Illegal number of parameters"
exit 1
fi
# Check file
if [ ! -f "${1}" ]; then
>&2 echo "File ${1} not found"
exit 1
fi
FILE="${1}"
while read line; do
USER=`echo ${line} | cut -d"," -f1`
ROLE=`echo ${line} | cut -d"," -f2`
PASS=`echo ${line} | cut -d"," -f3`
echo "adding user ${USER} (role: ${ROLE}) with password: ${PASS}"
esusers useradd "${USER}" -r "${ROLE}" -p "${PASS}"
done < ${FILE}
Then, add execution mode to the script with chmod +x script.sh
and run the script with the csv file as parameter ./script.sh user.csv
$ ./script.sh user.csv
adding user user1 (role: role1) with password: pass1
adding user user2 (role: role2) with password: pass2
adding user user3 (role: role3) with password: pass3

How to change file permission while doing ssh in shell

I am using the below codes to change some file permissions:
encrypt=`sed -n '/:/,$p' $FILE_PATH_1 | cut -d':' -f2 | tr -d ' '`
local listOfPasswordChangeWS=`$SMANAGER_SCRIPT status service PasswordChangeWS | cut -f 2 -d ":"`
for node in $listOfPasswordChangeWS ; do
ssh -q $i "cp /opt/oss/NSN-mf_swp/smx/mf-conf/was-cred.properties /opt/oss/NSN-mf_swp/smx/mf-conf/was-cred.properties.original"
ssh -q $i "sed -i '/Password/c\com.ibm.CORBA.loginPassword=ENC($encrypt)' /opt/oss/NSN-mf_swp/smx/mf-conf/was-cred.properties "
**ssh -q $i "chown -c omc:sysop /opt/oss/NSN-mf_swp/smx/mf-conf/was-cred.properties ; chmod 640 /opt/oss/NSN-mf_swp/smx/mf-conf/was-cred.properties"**
# INCR=$?
INCR=$?
if [ "INCR" == "0" ] ; then
NewIncr++
fi
done
I want to check the exit status but since it is in for loop i am not able to get value 0 or 1 instead it is returning value 255. My query is:
1. How can I check the exit status of chown -c command (Remember i am doing ssh)
2. How can I check whether my file permission has been changed to omc:sysop
Try this:
if ssh $HOST 'chown -c omc:sysop /opt/oss/NSN-mf_swp/smx/mf-conf/was-cred.properties ; chmod 640 /opt/oss/NSN-mf_swp/smx/mf-conf/was-cred.properties' < /dev/null
if [ $? -eq 0 ]; then
echo SUCCESS
else
echo FAIL
fi

Resources