BASH: append loop output to an email - bash

I want the output of this script to be a body of the email message but I don't want to redirect it to a file first and then to an email, basically no external login/output files - all action should be done within the script itself - is it possible to do it?
Example:
#!/bin/bash
email() {
echo "Results:"
}
for i in $(ls -1 test); do
if [ -f "test/$i" ]; then
echo "'$i' it's a file."
else
echo "'$i' it's a directory."
fi
done
email | mail -s "Test" an#example.com
Output:
$ ./tmp.sh
'd1' it's a directory.
'f1' it's a file.

It's easy:
#!/bin/bash
email() {
echo "Results:"
cat
}
for i in $(ls -1 test); do
if [ -f "test/$i" ]; then
echo "'$i' it's a file."
else
echo "'$i' it's a directory."
fi
done |email | mail -s "Test" an#example.com
You need the output of your test as input of email function, note that cat is just letting it pass through.

Related

Im trying to get variable that is in a here document (EOF) to echo or store in the script outside the EOF

Im writing a script the i add later as a cronjob, so this script has functions and inside it uses a here document to execute commands on remote server
there is a variabe "result" in this script that will tel the state of the hosts
I need the same variable "result" to echo outside of the here document (EOF)
How do i do this
one(){
ssh_cmd="$(cat <<-EOF
echo --------------------------------------------------------------
echo "Checking testapp Status on Domain Controller --> host = slave1 "
echo --------------------------------------------------------------
result=(\$(/opt/jboss/web/bin/jboss-cli.sh --connect controller=10.0.0.4:9990 --commands='ls /host=slave1/server-config=testapp' | grep 'status=' | awk 'FNR%2' | sed -r 's/.{7}//'))
echo ----------------
echo "\${result[#]}"
echo ----------------
if [ "\${result[#]}" != "STARTED" ];
then
echo --------------------------------------
echo "Starting the server"
echo --------------------------------------
/opt/jboss/web/bin/jboss-cli.sh --connect controller=10.0.0.4:9990 --commands='/host=slave1/server-config=testapp:start'
else
echo --------------------------------------
echo "Server is running"
echo --------------------------------------
fi
EOF
)"
ssh -t root#someserver "$ssh_cmd"
}
echo $result
if [ $result == value];
then
two (run function two)
else
exit
need the same variable "result" to echo outside of the here document (EOF)
Then you need to send it, no other way. You could send it using the output of ssh:
....
# output the value.
echo "unique_string_with_result=$result"
EOF
)"
# get ssh output to a file
ssh ..... | tee tempfile.txt
# filter the output and extract the value
result=$(sed -n 's/unique_string_with_result=//p' tempfile.txt)
}

bash script not running properly

When I run this by its self in the command line it seems to work fine, but when I have another script execute this, it doesn't work. Any ideas? I'm guessing it has to do with quotes, but not sure.
#!/bin/sh
#Required csvquote from https://github.com/dbro/csvquote
#TODO: Clean CSV File using CSVFix
#Version 3
echo "File Name: $1"
function quit {
echo "Quitting Script"
exit 1
}
function fileExists {
if [ ! -f "$1" ]
then
echo "File $1 does not exists"
quit
fi
}
function getInfo {
#Returns website url like: "http://www.website.com/info"
#Reads last line of a csv file, and gets the 2nd item.
RETURN=$(tail -n 1 $1 | csvquote | cut -d ',' -f 2 | csvquote -u)
echo $RETURN
}
function work {
CURLURL="http://127.0.0.1:9200/cj/_query"
URL=$(getInfo)
echo "URL: $URL"
CURLDATA='{ "query" : { "match" : { "PROGRAMURL" : '$URL' } } }'
#URL shows up as blank...???
echo "Curl Data: $CURLDATA"
RESPONSE=$(curl -XDELETE "$CURLURL" -d "$CURLDATA" -vn)
echo $RESPONSE
echo "Sleeping Allowing Time To Delete"
sleep 5s
}
fileExists $1
work $1
I cant see why a simpler version wont work: functions are useful, but I think there are too many, overcomplicating things, if what you are posting is the entirety of your script (in my opinion)
Your script is doing things using a broken lucky pattern: $1 variables are also arguments to shell functions as well as the main script. Think of them as local variables to a function. So when you are calling $(getInfo) it is calling that function with no argument, so actually runs tail -n 1 which falls back to stdin, which you are specifying to work as < $1. You could see this for yourself by putting echo getInfo_arg_1="$1" >&2 inside the function...
Note also you are not quoting $1 anywhere, this script is not whitespace in file safe, although this is only more likely to be a problem if you are having to deal with files sent to you from a Windows computer.
In the absence of other information, the following 'should' work:
#!/bin/bash
test -z "$1" && { echo "Please specify a file." ; exit 1; }
test -f "$1" || { echo "Cant see file '$1'." ; exit 1; }
FILE="$1"
function getInfo() {
#Returns website url like: "http://www.website.com/info"
#Reads last line of a csv file, and gets the 2nd item.
tail -n 1 "$1" | csvquote | cut -d ',' -f 2 | csvquote -u
}
CURLURL="http://127.0.0.1:9200/cj/_query"
URL=$(getInfo "$FILE")
echo "URL: $URL"
CURLDATA='{ "query" : { "match" : { "PROGRAMURL" : '$URL' } } }'
curl -XDELETE "$CURLURL" -d "$CURLDATA" -vn
echo "Sleeping Allowing Time To Delete"
sleep 5s
If it still fails you really need to post your error messages.
One other thing, especially if you are calling this from another script, chmod +x the script so you can run it without having to invoke it with bash directly. If you want to turn on debugging then put set -x near the start somewhere.

Script to monitor any modifications in files in my FTP site

Iam trying to build a script to monitor any modifications in files in my FTP site. The script is given below. I have used wc -l to count the no. of files in the directory and have defined the constant value of files if there is going to be any modification in files like if my co-worker updates in my FTP this will send me a notification. Am trying to cron this to achieve. But the script actually just hangs after the count . It doesn't provide me the expected result. Is there anything that am wrong with the code. Am just a beginner in Bash could anyone help me solve this
#!/usr/bin/bash
curl ftp://Sterst:abh89TbuOc#############################/Test/| wc -l ;
read b;
a=9
if [ "$b" != "$a" ];
then
echo "FTP dir has modified mail" -s "dir notification" sni912#######.com;
fi
A couple of notes about your code:
#!/usr/bin/bash
curl ftp://Sterst:abh89TbuOc#############################/Test/| wc -l ;
read b;
That does not do what you think it does: the wc output goes to stdout, not into the read command. Do this instead: b=$( curl ... | wc -l )
a=9
if [ "$b" != "$a" ];
Since the wc output will have some extra whitespace, better to do a numeric comparison:
if (( a != b ))
then
echo "FTP dir has modified mail" -s "dir notification" sni912#######.com;
You probably mean this:
echo "FTP dir has modified" | mail -s "dir notification" sni912#######.com;
I would write this:
listing=$( curl ftp://... )
num=$( echo "$listing" | wc -l )
if (( num != 9 )); then
mail -s "ftp dir modification" email#example.com <<END
FTP directory modification
$listing
END
fi
My code
#!/usr/local/bin/bash
listing=$( curl ftp://username:password#ftp.com/test/ )
num=$( wc -l | echo "$listing" )
if (( num != 9 ));
then
mail -s "ftp dir modification" email#example.com
fi `

script to check last file modified

SHELL SCRIPT TO GET MAIL IF FILE GET MODIFIED
I am writing script to get mail if file has been modified
recip="mungsesagar#gmail.com"
file="/root/sagar/ldapadd.sh"
#stat $file
last_modified=$(stat --printf=%y $file | cut -d. -f1)
#echo $last_modified
mail -s "File ldapadd.sh has changed" $recip
Now I get mail when I run this script but I want to compare two variables so that I can get mail only if file modified or content changed.
How can I store output in variable to compare
Thanks in advance
Sagar
I'd do it this way:
recip="you#example.com"
file="/root/sagar/ldapadd.sh"
ref="/var/tmp/mytimestamp.dummy"
if [ "$file" -nt "$ref" ]; then
mail -s "File ldapadd.sh has changed" $recip
fi
touch -r "$file" "$ref" # update our dummy file to match
The idea is to store the last seen timestamp of the file of interest by copying it to another file (using touch). Then we always know what the last time was, and can compare it against the current timestamp on the file and email as needed.
If I understand your question correct, the logic can be changed by storing the output of "ls -ltr filename" in a temp1 file and comparing the same with the ls -ltr output
I would use find to see the last modifyed file
#!/bin/bash
file=timestamp.txt
if [ ! -f timestamp.txt ];
then
stat -f %Sm -t %Y%m%d%H%M%S $file > timestamp.txt
else
timestamp=$(stat -f %Sm -t %Y%m%d%H%M%S $file)
filetime=$(cat filetime.txt)
if [ "$filetime" = "$timestamp" ];
then
#Do nothing
else
echo "$file has been modified" >> /tmp/email.txt
mail -s "File has changed" "email#domain.com" < /tmp/email.txt
fi
fi

Finding and adding a word to a particular line using shell script with exact format of a file

My problem is to add a username to a file, I really stuck to proceed, please help.
Problem: I am having a file called usrgrp.dat. The format of this file is like:
ADMIN:srikanth,admin
DEV:dev1
TEST:test1
I am trying to write a shell script which should give me the output like:
Enter group name: DEV
Enter the username: dev2
My expected output is:
User added to Group DEV
If I see the contents of usrgrp.dat, it should now look like:
DEV:dev1,dev2
TEST:test1
And it should give me error saying user already present if I am trying to add already existing user in that group. I am trying this out with the following script:
#!/bin/sh
dispgrp()
{
groupf="/home/srikanth/scm/auths/group.dat"
for gname in `cat $groupf | cut -f1 -d:`
do
echo $gname
done
echo "Enter the group name:"
read grname
for gname in `cat $groupf | cut -f1 -d:`
do
if [ "$grname" = "$gname" ]
then
echo "Enter the username to be added"
read uname
for grname in `cat $groupf`
do
$gname="$gname:$uname"
exit 1
done
fi
done
}
echo "Group display"
dispgrp
I am stuck and need your valuable help.
#!/bin/sh
dispgrp()
{
groupf="/home/srikanth/scm/auths/group.dat"
tmpfile="/path/to/tmpfile"
# you may want to pipe this to more or less if the list may be long
cat "$groupf" | cut -f1 -d:
echo "Enter the group name:"
read grname
if grep "$grname" "$groupf" >/dev/null 2>&1
then
echo "Enter the username to be added"
read uname
if ! grep "^$grname:.*\<$uname\>" "$groupf" >/dev/null 2>&1
then
sed "/^$grname:/s/\$/,$uname/" "$groupf" > "$tmpfile" && mv "$tmpfile" "$groupf"
else
echo "User $uname already exists in group $grname"
return 1
fi
else
echo "Group not found"
return 1
fi
}
echo "Group display"
dispgrp
You don't need to use loops when the loops are done for you (e.g. cat, sed and grep).
Don't use for to iterate over the output of cat.
Don't use exit to return from a function. Use return.
A non-zero exit or return code signifies an error or failure. Use 0 for normal, successful return. This is the implicit action if you don't specify one.
Learn to use sed and grep.
Since your shebang says #!/bin/sh, the changes I made above are based on the Bourne shell and assume POSIX utilities (not GNU versions).
Something like (assume your shell is bash):
adduser() {
local grp="$1"
local user="$2"
local gfile="$3"
if ! grep -q "^$grp:" "$gfile"; then
echo "no such group: $grp"
return 1
fi
if grep -q "^$grp:.*\\<$user\\>" "$gfile"; then
echo "User $user already in group $grp"
else
sed -i "/^$grp:/s/\$/,$user/" "$gfile"
echo "User $user added to group $grp"
fi
}
read -p "Enter the group name: " grp
read -p "Enter the username to be added: " user
adduser "$grp" "$user" /home/srikanth/scm/auths/group.dat

Resources