Bash script to search for LDAP entries - bash

I have a bash script which is to be used to delete a particular user if it exists in a group.
First I extracted all the group names and saved it to a file. As the next step, I thought I should parse through the file, and use the ldapsearch command on all the entries and grep the user, and if it exists, use ldapmodify to delete it.
My question is how to write the if condition, i.e if [ *ldapsearch query* == True];then
This is what my ldapsearch looks like, and the first line inside the while loop is to be the if statement.
while read grp;do
ldapsearch -w 'ldappass' -D "cn=adminuser,dc=some-domain,dc=com" -b "cn=$grp,ou=group,dc=some-domain,dc=com" | grep $someuser
done</home/someuser/tempfile.txt
On the CLI, this ldapsearch query returns the following output;
memberUid: testuser
So essentially, if the if statement returns some value (i.e. the user exists), then I have to delete the user. How do I get a correct if statement to get a True or False result for the ldapsearch query?

You can use the -z option, that checks if the string is empty or not. [ -z "$string" ] is true if the string is empty. Then, this can make it:
if [ ! -z "$(yourcommand)" ]; then
do_things
fi
For example say we want to check if a directory is empty:
if [ ! -z "$(ls)" ]; then
echo "there is something"
else
echo "this dir is empty"
fi
All together:
while IFS= read -r grp;do
if [ ! -z "$(ldapsearch -w 'ldappass' -D "cn=adminuser,dc=some-domain,dc=com" -b "cn=$grp,ou=group,dc=some-domain,dc=com" | grep $someuser)" ]; then
remove $someuser
fi
done < /home/someuser/tempfile.txt

Related

Shell Script reading Enter key as an Input

I want to use the enter key as an input for a certain command.
But when there is no input I want to just loop.
If I write script like this then as the read command execution ends after 3 seconds with no input. it does not loop, but executes my desired output for enter key input command.
How can I fix this?
while true;
do
read -s -t 3 -n 3 key
if [ "${key}" == $'\0A' ]; then
#do something
elif [ "$key" == ""]; then
continue
fi
done
You have two problems, when using a character-literal in bash (it's bash-only), you need to use the actual-character, e.g.
if [ "${key}" == $'\n' ]; then
Next the equality comparison with [ ... ] is = not == (though bash will accept the latter). However, you must have a space before the closing ] in:
elif [ "$key" = "" ]; then
Making those changes the loop will loop continually with a 3-second timeout waiting for 3-characters of input in the manner you want, e.g.
#!/bin/bash
while true;
do
echo "looping"
read -s -t 3 -n 3 key
if [ "${key}" == $'\n' ]; then
echo "enter key"
elif [ "$key" = "" ]; then
continue
else
echo "key $key"
fi
done
Give it a go and let me know if you have further questions.
Edit Per Comment
If you want to execute a function on timeout, then you need to check the return of read. When a timeout occurs, the return will be greater than or equal to 128. If you then want to catch the Enter key, use an else and then check for an empty key, that will show that enter alone was pressed. Otherwise, you hae 3-chars in key, e.g.
#!/bin/bash
while true;
do
echo "looping"
read -s -t 3 -n 3 key
if [ $? -ge 128 ]; then
echo "timeout - execute function"
else
if [ "$key" = "" ]; then
echo "enter key"
continue
else
echo "key $key"
fi
fi
done
Example Use/Output
$ bash test.sh
looping
timeout - execute function
looping
timeout - execute function
looping
enter key
looping
timeout - execute function
looping
key foo
looping
enter key
looping
If I have the timeout/empty reversed, just switch the logic. I'm still not 100% clear on your comment, but I think this is what you indicated.
Since you want to re-ask the input if the user did not input an enter, I'd suggest to change the while true to something like while [[ "${key}" != $'\0A' ]]. THis way you can re-ask the input until it's an enter, and run your command after the while.
Would look something like:
# Read first time
read -s -t 3 -n 3 key
# If this wasn't an enter, keep asking until it is
while [[ "${key}" != $'\0A' ]]; do
read -s -t 3 -n 3 key
done
# Done
echo 'Running special command'

(Ubuntu bash script) Setting rights from a config txt

I am a beginner and trying to write a script that takes a config file (example below) and sets the rights for the users, if that user or group doesn´t exist, they get added.
For every line in the file, I am cutting out the user or the group and check if they exist.
Right now I only check for users.
#!/bin/bash
function SetRights()
{
if [[ $# -eq 1 && -f $1 ]]
then
for line in $1
do
var1=$(cut -d: -f2 $line)
var2=$(cat /etc/passwd | grep $var1 | wc -l)
if [[ $var2 -eq 0 ]]
then
sudo useradd $var1
else
setfacl -m $line
fi
done
else
echo Enter the correct path of the configuration file.
fi
}
SetRights $1
The config file looks like this:
u:TestUser:- /home/temp
g:TestGroup:rw /home/temp/testFolder
u:TestUser2:r /home/temp/1234.txt
The output:
grep: TestGroup: No such file or directory
grep: TestUser: No such file or directory
"The useradd help menu"
If you could give me a hint what I should look for in my research, I would be very grateful.
Is it possible to reset var1 and var2? Using unset didn´t work for me and I couldn´t find variables could only be set once.
It's not clear how you are looping over the contents of the file -- if $1 contains the file name, you should not be seeing the errors you report.
But anyway, here is a refactored version which hopefully avoids your problems.
# Avoid Bash-only syntax for function definition
SetRights() {
# Indent function body
# Properly quote "$1"
if [[ $# -eq 1 && -f "$1" ]]
then
# Read lines in file
while read -r acl file
do
# Parse out user
user=${acl#*:}
user=${user%:*}
# Avoid useless use of cat
# Anchor regex correctly
if ! grep -q "^$user:" /etc/passwd
then
# Quote user
sudo useradd "$user"
else
setfacl -m "$acl" "$file"
fi
done <"$1"
else
# Error message to stderr
echo Enter the correct path of the configuration file. >&2
# Signal failure to the caller
return 1
fi
}
# Properly quote argument
SetRights "$1"

Read unix log for message and then perform action

I am looking to create a shell script to read the message log and when finds the correct string perform an action. So far I have the following:
#!/bin/bash
string="ntp engine ready"
tail -n 0 -f /var/log/messages | \
while read LINE
do
echo "$LINE | grep -q $string"
if [ $? == 0];then
shttpclient "http://127.0.0.1/do/action"
fi
done
But, I get the following error:
grep: engine: No such file or directory
grep: ready: No such file or directory
Even when I see the logger has outputted ntp engine ready.
Firstly, you need to fix your quotes:
echo "$LINE" | grep -q "$string"
Secondly, you can simply do:
if echo "$LINE" | grep -q "$string"; then
rather than checking the return code $? manually. Remember that [ is a command too and if is just checking its return code.
If you do need to use [, remember that ] is an argument to the command so it is essential to surround it with spaces:
if [ $? = 0 ]
I have also removed the second = as it is a bash extension to support it. Actually you are doing an integer comparison, so really it should be one of the following:
if [ $? -eq 0 ] # POSIX compliant
if (( $? == 0 )) # bash arithmetic context
Alter the line as follows:
echo "$LINE" | grep -q "$string"
The quotes were not set correctly. Like when you execute that: grep -q ntp engine ready; ntp is the string to search and engine and ready are the files. It must look like: grep -q "ntp engine ready".

parsing a csv file $INPUT, write to $OUTPUT, and prompt for user input all in a while loop - user NOT prompted

I have a problem, and I am pretty new to writing bash. I am parsing a csv file, checking for a few things. If a check is true, change the variable which will later be written to a file. I am reading an input file and outputting to a file as well, and If a certain argument checks True, then I want to prompt the user and pause the script until the user verifies the information matches (manual verification).
I have my most recent attempt which is not prompting. It just continues to read and write to the output. I am pretty sure because the output is going directly to my output file, but I do not know a way to direct the prompt to the terminal window which is where I am stuck.
INPUT=$TMPSAVE
IFS=,
[ ! -f $INPUT ] && { echo "$INPUT file not found"; exit 99; }
while read cdwon cdwod manu_date hp_sn manu_sn wiped_by wiped_date checked_by disposition readonly
do
for i in ${!allassigned[#]}
do
if [[ -n $manu_sn ]]
then
if echo ${allassigned[i]} | grep -q $manu_sn
then
physicaldrive=${allassigned[i-1]}
disk=$(hpacucli ctrl slot=${SLOT} show config detail | grep -B 4 ${physicaldrive} | head -1 | awk '{print $NF}');
if [[ -n $disk ]]; then #proceed to wipe drive
mount ${disk}${PRIMARY} ${MOUNT}
if [ -e $DIR ]; then
####### the file exists, now what to do with it? Automatcially prompt user?
cat $DIR > /dev/tty
echo "Does the drive serial number (${allassigned[i]}) match what was provided from the database ($manu_sn)? (y/n)" > /dev/tty
read
if [ "$REPLY" == "Y" ] || [ "$REPLY" == "y" ] || [ "$REPLY" == "YES" ] || [ "$REPLY" == "yes" ]; then
checked_by=$username
checked_bydate=`date`
fi
fi
fi
fi
fi
done
echo "$cdwon,$cdwod,$manu_date,$hp_sn,$manu_sn,$wiped_by,$wiped_date,$checked_by,$disposition,$readonly";
continue;
done < $INPUT > $OUTPUT
I solved my own issue here. I found out that read by default is reading from the stdin. When I was trying to prompt for input it was using stdin, so the lines I was reading were technically the stdin input. If you want to read a file in a while loop with the method I have done you have to change the fd like so:
while read -u 6 column1 column2
do
.....body
done 6< $INPUTFILE
Key being the "6" which could be any arbitrary number.

If fails or copy function fails?

I have a little bash script where I compare two files. If one doesn't exist and second one exists, then I will copy/replace backup to main folder.
Somehow this doesn't seem to work. Hope someone can give a hand on this one:
#!/bin/bash
if [ ! -f "/Folder1/$1.jpg" ] && [ -f "/BU_Folder2/$1_BU.jpg" ]; then
cp -fp /BU_Folder2/$1_BU.jpg /Folder1/$1.jpg
cp -fp /BU_Folder2/$1_BU.mp4 /Folder1/$1.mp4
fi
At the prompt, run the following commands:
$ set -- FILENAME # FILENAME is the value you think $1 is supposed to have
$ [ ! -f "/Folder1/$1.jpg" ] && [ -f "/BU_Folder2/$1_BU.jpg" ] && echo success
If the last command does not print "success", then your script probably does not have the value for $1 that you think it does. Add echo $1 to the top of your script to confirm.
If it does print "success", and your script has no error output from cp, I'm not sure what to suggest.

Resources