How to send email from remote server for particular user via unix shell script [closed] - linux

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I need to send mail to a particular user from host computer via shell script using command line argument.Mail should go to that particular user only.
Script execution will be like ./tesh.sh user emailid
cat test.sh
#!/bin/sh
export user=$1
export email=$2
list=`echo "$(cat ip.txt)"`
script=$(cat remote_cmds.sh)
for ip in ${list[#]} ; do
echo "***";
echo "IP: $ip"
ssh -o StrictHostKeyChecking=no -l ${user} ${ip} ${script}
done
# cat remote_cmds.sh
source pathto/test.sh
echo "";
echo "****Hostname****";
echo "`hostname`";
echo "";
echo "****Disk Allocated****";
echo "`df -h`";
echo "";
echo "****Ram Allocated****";
echo testmail | mailx -s "Testmail" $email

If I understand you correctly you have N computers with ip addresses saved in ip.txt. Each of these computers has a user named 'user' to which you can login via ssh. Each of these computers has a user named 'emailid' to which you want to send mail. You want to use ssh session to connect to these computers and run mail client on these computers. You want to print some information about hostname, disc space and some other infos from the remote computers on your computer and send simple mail with subject 'Testmail' and content 'testmail' to the local user 'emaillid' on these remote N computers.
These scripts are not good. Doing script=$(cat remote_cmds.sh) and then calling ssh ... ${scripts} is so dangerous... The line list=echo "$(cat ip.txt)" can be just shortened to list=$(cat ip.txt). list variable is not an array, so doing ${list[#]} is the same as $list. remote_cmds.sh has the line source pathto/test.sh, so that means that each of N computers has a test.sh file in the same path?
mailx is giving you arror, cause you are executing (literally) mailx -s Testmail $email and email address can't have $ characters (the email variable is not expanded).
Try smth like this:
test.sh
#!/bin/sh
# export is not needed anywhere here
user=$1
email=$2
# loop through the lines in ip.txt
cat ip.txt | while read ip; do
echo "***";
echo "IP: $ip"
# https://unix.stackexchange.com/questions/87405/how-can-i-execute-local-script-on-remote-machine-and-include-arguments
# login on computer with ip $ip on user $user and execute command on
# remote host 'bash -s', which will read commands from standard input,
# append our remote_cmds.sh script to stdin and pass "$email" as first
# argument to this script
ssh -o StrictHostKeyChecking=no -l "$user" "$ip" bash -c -- < remote_cmds.sh "$email"
done
# this loop is bad and inefficient, but it's safe and simple to write
# see https://stackoverflow.com/questions/1521462/looping-through-the-content-of-a-file-in-bash
remote_cmds.sh
#!/bin/sh
# these lines will be executed on N computers
# email is passed as first argument to this script
email=$1
echo "";
echo "****Hostname****";
hostname
echo "";
echo "****Disk Allocated****";
df -h
echo "";
echo "****Ram Allocated****";
free -h # ;)
echo testmail | mailx -s "Testmail" "$email"

Related

My script is working fine butit is not taking next server from the server list [duplicate]

This question already has answers here:
While loop stops reading after the first line in Bash
(5 answers)
Closed yesterday.
My script is working fine butit is not taking next server from the server list
#!/bin/bash
# Read in server names from afile
while read -r server; do
# Check if server is reachable
if ping -c 1 "$server" &> /dev/nul l; then
echo "Server $server is reachable."
# Check if mount point exists
if ssh "$server" "[ -d /path/to/mount/point ]"; then
echo "Mount point exists on server $server."
else
echo "Mount point does not exist on server $server."
fi
else
echo "Server $server is not reachable."
fi
done < servers.txt
For an example 192.168.0.1 and 192.168.0.2 is there in server list file .but it is showing output for 192.168.0.1 . It is not showing output for 192.168.0.2
As pointed out in the comments section, ssh command is consuming your script stdin.
Add -n option to ssh should prevent this (see this).
So change this line:
if ssh "$server" "[ -d /path/to/mount/point ]"; then
To:
if ssh -n "$server" "[ -d /path/to/mount/point ]"; then

Capturing SSH Output in a variable in a bash script

I'm trying to SSH into another machine and caputre it's ip address and hostname into a variable.
However, the varaible seems to be empty when i echo it.
I have tried out answers from other posts, but it didnt solve my problem. I'm not able to figure out as what the problem is.
#!/bin/bash
FILE=/home/admin/Vishal/output.txt
input=host.txt
while IFS= read -r line
do
echo "$line"
if [ $line = $HOSTNAME ]
then
ip=`hostname -i`
domain=`hostname -A`
host=`hostname`
sudo echo $ip $domain $line localhost >> $FILE
else
output=$(ssh -i -t admin#$line << "ENDSSH"
ip2=`hostname -i`
domain2=`hostname -A`
host2=`hostname`
ENDSSH
)
echo $output
fi
done <"$input"
The input file contains a list of hostnames
The variable FILE contains the path of the file where the results are to be stored.
The varaible output is the one in which i want to store the results.
Note: The script works for first part of the if where ssh isnt required.
Ony this command is relevant for your quesion:
output=$(ssh -i -t admin#$line << "ENDSSH"
ip2=`hostname -i`
domain2=`hostname -A`
host2=`hostname`
ENDSSH
)
The command sets some variables, but doesn't produce any output, so it's expected that output does't contain your values.
If you really want three lines with hostname related values, then something simple like this should work
output=$(ssh admin#$line "hostname -i; hostname -A; hostname")

Script only processes 1st Line of input file [duplicate]

This question already has answers here:
ssh breaks out of while-loop in bash [duplicate]
(2 answers)
Closed 4 years ago.
bash script to read a file and process commands remotely.
It currently only processes the first line (server1)
Need to remotely process 3 commands on server1 , then server2 ......
#!/bin/bash
while read line; do
sshpass -f password ssh -o StrictHostKeyChecking=no user#$line zgrep "^A30=" /var/tmp/logs1/messages.* | >> Output.txt
sshpass -f password ssh -o StrictHostKeyChecking=no user#$line zgrep "^A30=" /var/tmp/logs2/messages.* | >> Output.txt
sshpass -f password ssh -o StrictHostKeyChecking=no user#$line zgrep "^A30=" /var/tmp/logs3/messages.* | >> Output.txt
done < file1
file1:
server1
server2
server3
sshpass is reading from the same file descriptor as the while loop, and exhausting that input before read is able to read it. Best thing is to close its stdin explicitly sshpass <&- ... or redirect from /dev/null sshpass < /dev/null.
Another option is to let sshpass inherit stdin from the script and read from a different file descriptor:
while read line <&3; do
...
done 3< file1

Run Bash Script followed by keyword or Variable

I tried to search for an answer online but found it hard to phrase the search criteria to find what I'm looking for. For starters I'm a total noob to coding/scripting.
Where I have gotten is understanding how to use the read function inside a script to create variables from user input which is great. My question is can you run a script followed by a keyword which would signify a hostname(target) device. This would look something like this.
sample.sh hostname
Currently my understanding only allows me add the hostname into a variables after the script is ran but this seems a little slower. A case of what I'd like is a generic script that checks interface status on a networking switch. It would be great to have the script setup in a way that I could run it followed by a hostname to just quickly check that single device. I think I am missing some fundamental understanding.
I hope I described that clearly, thanks for any help in advance. I have a sample bash script below and the expect script that it's passed onto
#!/bin/bash
echo "What device do you want to check TRUNK links?"
read -e host
echo "Username:"
read -e user
echo "Password:"
read -s -e password
./show-trunk.exp $host $user $password;
#!/usr/bin/expect -f
set host [lindex $argv 0]
set user [lindex $argv 1]
set password [lindex $argv 2]
#spawn echo "Running Script..."
log_user 0
spawn ssh $username#$devices
expect "*assword:"
send "$password\r"
expect "#"
log_user 1
send "show int desc | in TRUNK\r"
expect "#"
send "exit\r"
There are special variables in bash that signify the arguments put into them. You can specify them like this:
#!/usr/bin/env bash
echo $1 $2 $3
Then to run the script on the command line:
~> ./test.sh hello bash user
hello bash user
If you need to test for the correct number of arguments, you can do a simple if statement like this:
#!/usr/bin/env bash
if [[ "$#" -eq 3 ]]; do
echo $1 $2 $3
else
echo "Not enough arguments"
fi
Then if you call it on the command line:
~> ./test.sh hello bash user
hello bash user
~> ./test.sh oops
Not enough arguments

Bash script does not ssh all the entries of a csv file

I am trying to patch a bunch of CENT OS machines with the latest fix pack. I have the below bash script that takes csv file as a input which has the ip address and password for those machines.
The code works fine however, it would only work for the first row it does not seem to be working for the rest of the list as my output.txt only has the entry only for the first row host .
patch.sh
INPUT=hosts_test.cvs
OLDIFS=$IFS
IFS=,
[ ! -f $INPUT ] && { echo "$INPUT file not found"; exit 99; }
while read privateip password
do
sshpass -p$password ssh -t -o "StrictHostKeyChecking no" user123#$privateip "
hostname
hostname -I --all-ip-addresses
sudo yum -y update bash
env x='() { :;}; echo vulnerable' bash -c \"echo If you see the word vulnerable above, then you are vulnerable to shellshock\"
echo ""
exit
" >> output.txt
done < $INPUT
IFS=$OLDIFS
hosts_test.cvs
10.xxx.xx.219,abcd~qY1
10.xxx.xx.226,l4~abcdefg
10.xxx.xx.221,l4#abcdefgh
Terminal Output
Pseudo-terminal will not be allocated because stdin is not a terminal.
Add at the end of your sshpass command </dev/null.
Add Defaults:username !requiretty to your /etc/sudoers config
Get rid of -t from your ssh command
Optional, but recommended: set up public key auth so you don't have your passwords lying around in text files.
You can pass ssh another -t to force pty allocation:
ssh -t -t

Resources