if condition for when a token is not found in a shell script - linux

I am trying to construct an if-else block wherein one of the conditions is to echo a message if, when running a grep command on a text file, the specified token can not be found.
The grep command is
grep -i -n "token" file | cut -d':' -f 1
If the token is found, it will return the line number as usual. I want to know how to account for the case when the token does not exist in the text file and the terminal simply outputs nothing when the command is executed.
i.e.
if []
then
echo "This token does not exist in the file"
fi

I hope that's what you need:
result=$(grep -i -n "token" file | cut -d':' -f 1)
if [[ -z "$result" ]]; then
echo "Not found"
else
echo "$result"
fi

Related

getting first column of a matching line in bash

I am getting an output from a shell command, and want to incorporate the first column of a matching line into a second command. Here is what I have, and it works:
kubectl get pods -n system | while read string; do
if [[ "$string" == my-pod-* && "$string" == *Running* ]]; then
# echo $string
read -ra ADDR <<< "$string"
echo
echo "--- Reading logs for ${ADDR[0]} ---"
# desired output: kubectl -n system logs my-pod-123 --tail=5 -f
kubectl -n system logs ${ADDR[0]} --tail=5 -f
fi
done
the output from first command would look something like this:
name status namespace running
my-pod-123 Running system 4h31m #<<I want this one
another-pod-5 Running system 5h15m
my-pod-023 Terminating system 8h05m
given that the output will contain only one match, is there a shorter way to do this without looping like this? Thanks in advance for helping me improve my Bash skills as this seems very clumsy.
You may use awk like this:
name=$(kubectl get pods -n system | awk '/^my-pod.*Running/{print $1}')
[[ -n $name ]] && kubectl -n system logs "$name" --tail=5 -f
awk command will match pattern my-pod.*Running at the start of a line and if it is found then it will print first column. We store that in variable name.
If $name is not empty then we call kubectl -n system logs using that value.
How about grep?
wanted=$(kubectl get pods -n system | grep 'my-pod-.*Running')
Can do error checking at the same time:
if ! wanted=$(kubectl get pods -n system | grep 'my-pod-.*Running'); then
echo "Error: no running my-pods" >&2
fi

WHOIS BASH Script sometimes not fetching data

My whois bash script works for a few domains and doesn't for others.
When I run the command directly in my terminal for the same domain, I am able to see output. Also, sometimes the script will not run properly and gets stuck, then I need to interrupt that.
Why is that, and how can I fix it?
Let's say the domain.txt file contains: gmail.com, zoom.us, facebook.com, bank.com etc.
The script is:
#!/bin/bash
echo "Please enter the full path of txt file"
read path
filename=$path
while read line
do
echo "Checking domain $line"
a=$(whois $line | grep -i -e "Creation Date" | head -1)
b=$(whois $line | grep -i -e "no match" | head -1)
echo "$a"$line >> /root/outputdomain.csv
done <$filename
echo "file has been processed successfully."
A sample input txt file is:
linkedin.com
zoom.us
sbi.co.in
facebook.com
sap.com
hsbc.com
Expected Output is:
Creation Date: 2002-11-02T15:38:11Z linkedin.com
Creation Date: 2002-04-24T15:03:39Z zoom.us
Whats is working for me currently:
Creation Date: 2002-11-02T15:38:11Z linkedin.com
Creation Date: 1997-03-29T05:00:00Z facebook.com
But no output for zoom.us, sbi.co.in.
If I run the command below, I am able to fetch the required data:
$ whois zoom.us | grep -E "Creation Date" | head -1
Creation Date: 2002-04-24T15:03:39Z
I don't use/know whois but base on your post this is what I came up with.
#!/usr/bin/env bash
shopt -s extglob
echo "Please enter the full path of txt file"
read -r path
filename=$path
while read -r line; do
printf 'Processing %s\n' "$line"...
if a=$(whois "$line" | grep --line-buffer -Fi -m1 "creation date"); then
printf '%s %s\n' "${a##*+([[:blank:]])}" "$line" >> outputdomain.csv
else
printf '%s No domain match\n' "$line" >> outputdomain.csv
fi
sleep 5
done < "$filename"
-m Might not be POSIX but it is in GNU and BSD grep.

Brute force bash script with another bash script

so i currently have a bash script that takes a hash value and then asks the user to input a password, converts their input to hash and then compares.
#!/bin/bash
crypt="8277e0910d750195b448797616e091ad"
echo "please enter a password!"
read inc
hash="$((echo -n $inc|md5sum) | awk '{print $1}')"
if [[ "$hash" == "$crypt" ]];
then
echo "logged in"
else
echo "incorrect pass"
fi
I now want to create another program that brute forces this password by adding values(from a-z) into the password input but im running into trouble as i feel my knowledge on bash file manipulation is limited as ive never ran a script against another script before.
#!/bin/bash
for i in {a..z}; do
(echo -n "$i: " && ./hashscript $i) | grep logged in
done
Since the 1st script is reading the data from stdin (with read), the 2nd script will need to pass the data in that way:
#!/bin/bash
for i in {a..z}; do
(echo -n "$i: " && echo $i | ./hashscript) | grep logged in
done

Beginner's Bash Scripting: "Unary Operator Expected" error && how to use grep to search for a variable from the output of a command?

I'm attempting to write a bash script that is executed through "./filename username" and checks whether or not that user is logged in, printing the result. I'm still new to scripting and am having trouble understanding how to make this work.
I'm currently getting the error "line 7: [: ambonill: unary operator expected". What does that mean and how can I go about fixing that error?
Additionally, how would I get grep to work instead of sort | uniq? I'd like to grep for the variable from the output of the command but can't find anything related in the man page.
#! /bin/bash
# This script will take a username as an argument and determine whether they are logged on.
function loggedin {
for u in `who | cut -f1 -d" " | sort | uniq`
do
if [ $u == $1 ]
then
echo "$1 is logged on"
else
echo "$1 is not logged on"
fi
exit 0
done
}
loggedin $u
exit 1
Try to find a simpler solution, like:
#!/bin/bash
echo "$1 is $([ -z "$(w -h $1)" ]&&echo -n not\ )logged on"

Shell Script to for remote copy and then processing the file

The below script works fine. But when I try to add a command to remote copy and then assign the variable FILENAME with the file received from the remote copy, the while loop doesn't work. I am quite new to scripting so I'm not able to find out what I'm missing. Please help!
#!/bin/sh
#SCRIPT: File processing
#PURPOSE: Process a file line by line with redirected while-read loop.
SSID=$1
ASID=$2
##rcp server0:/oracle/v11//dbs/${SSID}_ora_dir.lst /users/global/rahul/${ASID}_clone_dir.lst
##FILENAME=/users/global/rahul/${ASID}_clone_dir.lst
count=0
while read LINE
do
echo $LINE | sed -e "s/${SSID}/${ASID}/g"
count=`expr $count + 1`
done < $FILENAME
echo -e "\nTotal $count Lines read"
grep -v -e "pattern3" -e "pattern5" -e "pattern6" -e "pattern7" -e "pattern8" -e "pattern9" -e "pattern10" -e "pattern11" -e "
pattern12" ${ASID}_.lst > test_remote.test
When you say, "the while loop doesn't work", if you get an error message you should include that in your question to give us a clue.
Are you sure the rcp command is successful? The file /users/global/rahul/${ASID}_clone_dir.lst exists after the rcp is completed?
Btw your while loop is inefficient. This should be equivalent:
sed -e "s/${SSID}/${ASID}/g" < "$FILENAME"
count=$(wc -l "$FILENAME" | awk '{print $1}')
echo -e "\nTotal $count Lines read"

Resources