0

I have to login to remote servers via ssh and go to tmp folder and there I have to run the rm command. But when i am executing the below script it goes to the to the remote server but do not go to temp folder and neither run the rm command.

#!/bin/bash
for i in `cat list`
echo $server
echo "------------------------------------------"
ssh $server << MYCOMMANDS
cd /tmp
rm log52.log
MYCOMMANDS
3

3 Answers 3

2

The only real issue with your code is that your loop lacks do and done, which would give you syntax errors, and that you are using i as your loop variable but try to connect with some server variable that may well be unset.

Apart from that, you are using cat in an unquoted command substitution which is generally a bad idea if you don't know for certain that you will be reading strings without whitespace and filename globbing characters (most hosts' names are well behaved in this respect though).

It's most of the time better to read the input line by line like so:

while IFS= read -r remote; do
    ssh -n "$remote" 'rm -f /tmp/log52.log'
done <list

I'm using ssh -n here to stop ssh from reading its standard input stream (which would be connected to the list file). Without -n, ssh would read the remaining contents of list and your loop would only run a single iteration.

Alternatively, if you really want to read the commands from a here-document:

while IFS= read -r remote; do
    ssh -T "$remote" <<'END'
rm -f /tmp/log52.log
END
done <list

Here, I'm using ssh -T to explicitly disable pseudo-terminal allocation, which is not needed as we're not doing anything that requires user interaction. I'm doing that because ssh will notice that its standard input stream has data, so it'll warn us about not having a functioning terminal on the remote system to do interactive things with. We don't need -n with ssh here as we are reassigning the standard input stream for ssh from the here-document.

But the loop could be replaced by the single command

xargs -I {} ssh {} 'rm -f /tmp/log52.log' <list

... where the xargs utility will read lines from the file list, replace {} in the ssh command with a line read from the file and perform the action of accessing the remote systems to delete the specific file. I'm using rm -f to not cause an error if there is no file to delete.

Some implementations of xargs allows for parallel execution of the utility with e.g. -P 4 (would keep at most four concurrent ssh commands going at once).

0
0
#! /bin/bash
for i in `cat list`
do
    echo $i
    echo "-------------------------"
    ssh $i "rm /tmp/log52.log"
done

If you only need to remove the single file you may want to simply specify that in a one liner. Additionally, you may find it helpful to add -f to the rm.

-2

You can't simply redirect stdin of an ssh session like that. You should be seeing an error message something like:

Pseudo-terminal will not be allocated because stdin is not a terminal

You need to use the option -tt to ssh to force a pseudotty to be allocated. Try this:

#!/bin/bash
for i in `cat list`
echo $server
echo "------------------------------------------"
ssh -tt $server << MYCOMMANDS
cd /tmp
rm log52.log
MYCOMMANDS
8
  • 2
    Both you and the OP seems to have forgotten the do and the done bit of the loop (consider testing your own solutions). Also, a terminal should not be needed as none of the commands are interactive. In fact, using -T to explicitly disable pseudo-terminal allocation will get rid of the warning (which, by the way, is just a warning).
    – Kusalananda
    Commented May 27, 2021 at 19:09
  • True. These could be more easily passed as argument. I also forgot to mention that if you try to use a pseudotty/stdin redirection, when the here document completes it will leave stdin connected, so the list of commands should end with "exit" to exit the shell and disconnect. I think this is probably what the real issue is - it will execute on the first system, then hang because it doesn't disconnect from that system. On -T vs -tt I tend to tell people to use -tt and allocate the ptty so that it will work with commands that need one.
    – Philip
    Commented May 27, 2021 at 19:13
  • The connection with the remote host will terminate when the here-document has been redirected (at which point the remote shell receives end-of-file). An explicit exit should not be needed.
    – Kusalananda
    Commented May 27, 2021 at 19:16
  • 2
    You have not tested the script in your answer.
    – Kusalananda
    Commented May 27, 2021 at 19:26
  • 1
    I did answer the question.
    – Kusalananda
    Commented May 28, 2021 at 20:28

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .