I have an if
statement to calculate files and delete all except the latest three files. But I want to run this command remotely. How can I combine ssh
with an if
condition?
I tried this but no success.
#!/bin/bash
ssh -t [email protected] "cd /var/www/test.com/backup ;
if [ $(ls | wc -l) -lt 3 ]
then
echo "Less"
else [ $(ls -t *.tgz|awk 'NR >3'|xargs rm -f) ]
echo "deleted"
fi"
The error I got:
ls: cannot access *.tgz: No such file or directory
Yes you can exexute complex scripts via
ssh
This example uses a bash here document to generate the command string. In any case, passing scripts via ssh is error prone, because the quoting and escaping of variables is difficult (mind the backslash before the commands). If the script gets too complex, it is better to copy it via
scp
and then execute it on the target host.I did not try to fix your script, but here is an example on how counting and deleting on a remote host could work:
The
ls -t *.tgz
will not work, since the globbing is only happening on the local system. Also usingls
for counting files is not a good idea, since it also returns entries like.
,..
and directories.NOTE: there are in fact two layers to the question here. One is 'I want to execute a non-trivial task on a remote server accessible via SSH'. The other is 'I'm trying to pass a complex string to a command, and the argument ends up being different from what I intended.' I'm answering the low-level question without discussing whether the approach used is "right" (convenient, non-error-prone, secure etc.) for solving the high-level one. As indicated by the other answers and comments, it quite possibly isn't.
Your command line is mostly right; you only have to change the quoting a bit.
The main problem is that double-quoted strings are expanded by your local shell, and so the
$(...)
parts will be evaluated on your local system. To pass them over to the remote system, you have to enclose the script in single quotes.You also have some embedded quotation marks. In your original script, there are the arguments for the two
echo
s; if you change the outer quotation to single quotes, it will be the awk script. These effecitvely result in the quotation marks being omitted, which doesn't bother theecho
s, but it will mess up the awk script, as the greater-than sign will become output redirection. So after you change the outer quotation marks to single quotes, change those to double quotes.This is your script with the quoting fixed. The script may have other issues, I just fixed the syntax.
I think this whole complicated quoting stuff is proof enough to not use it but use a script instead. If you want to avoid multiple
ssh
connections, pipe the script over to the other host and let it run there in one command:Local file, say
myscript.sh
:Then:
Or (avoiding a useless use of cat):
This pipes the local script
myscript.sh
to the remote side where it is redirected to a (temporary) file/tmp/ms.sh
, executed, and finally removed.Note: I didn't check the original script for errors but just wanted to show the idea. No error prone quoting is necessary and all commands in the script are executed on the remote side.
I would prefer to place the script on the remote instance and just execute it through ssh, but here is my suggestion how this could be done in the way you want:
Notes:
-lt
is replaced by-le
.eval
- construct command by concatenating arguments.\"
within the$COMMAND{1..3}
expression, but I decide to add them.