Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shell Script ssh $SERVER >> EOF

Tags:

linux

bash

ssh

eof

I have a handy script here that can return accounts that will expire in 7 Days or have expired. I wanted to allow this to run on multiple hosts with out putting the script on each individual host, I added the for loop and the ssh $SERVER >> EOF part but it will just run the commands off they system that is running the script.

I believe the error is with ssh $SERVER >> EOF but I am unsure as the syntax looks correct.

#!/bin/bash

for SERVER in `cat /lists/testlist`
do
  echo $SERVER

  ssh $SERVER >> EOF
    sudo cat /etc/shadow | cut -d: -f1,8 | sed /:$/d > /tmp/expirelist.txt
    totalaccounts=`sudo cat /tmp/expirelist.txt | wc -l`
    for((i=1; i<=$totalaccounts; i++ ))
    do
      tuserval=`sudo head -n $i /tmp/expirelist.txt | tail -n 1`
      username=`sudo echo $tuserval | cut -f1 -d:`
      userexp=`sudo echo $tuserval | cut -f2 -d:`
      userexpireinseconds=$(( $userexp * 86400 ))
      todaystime=`date +"%s"`
      if [[ $userexpireinseconds -ge $todaystime ]] ;
      then
        timeto7days=$(( $todaystime + 604800 ))
        if [[ $userexpireinseconds -le $timeto7days ]];
        then
          echo $username "is going to expire in 7 Days"
        fi
      else
        echo $username "account has expired"
      fi
    done
    sudo rm /tmp/expirelist.txt
  EOF
done
like image 671
SpruceTips Avatar asked Nov 15 '25 22:11

SpruceTips


1 Answers

Here documents are started by << EOF (or, better, << 'EOF' to prevent the body of the here document being expanded by the (local) shell) and the end marker must be in column 1.

What you're doing is running ssh and appending standard output to a file EOF (>> is an output redirection; << is an input redirection). It is then (locally) running sudo, etc. It probably fails to execute the local file EOF (not executable, one hopes), and likely doesn't find any other command for that either.

I think what you're after is this (where I've now replaced the back-ticks in the script with $(...) notation, and marginally optimized the server list generation for use with Bash):

#!/bin/bash

for SERVER in $(</lists/testlist)
do
  echo $SERVER

  ssh $SERVER << 'EOF'
    sudo cat /etc/shadow | cut -d: -f1,8 | sed '/:$/d' > /tmp/expirelist.txt
    totalaccounts=$(sudo cat /tmp/expirelist.txt | wc -l)
    for ((i=1; i<=$totalaccounts; i++))
    do
      tuserval=$(sudo head -n $i /tmp/expirelist.txt | tail -n 1)
      username=$(sudo echo $tuserval | cut -f1 -d:)
      userexp=$(sudo echo $tuserval | cut -f2 -d:)
      userexpireinseconds=$(( $userexp * 86400 ))
      todaystime=$(date +"%s")
      if [[ $userexpireinseconds -ge $todaystime ]]
      then
        timeto7days=$(( $todaystime + 604800 ))
        if [[ $userexpireinseconds -le $timeto7days ]]
        then
          echo $username "is going to expire in 7 Days"
        fi
      else
        echo $username "account has expired"
      fi
    done
    sudo rm /tmp/expirelist.txt
EOF
done

Very close, but the differences really matter! Note, in particular, that the end marker EOF is in column 1 and not indented at all.

like image 85
Jonathan Leffler Avatar answered Nov 17 '25 21:11

Jonathan Leffler



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!