How can SSH work with an if condition?
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 test@192.168.94.139 "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
command-line bash ssh
add a comment |
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 test@192.168.94.139 "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
command-line bash ssh
Then how can I customize this?
– Janith
Dec 3 '18 at 5:30
@user68186 Why's that? The command is in quotes.
– Lightness Races in Orbit
Dec 3 '18 at 11:12
2
The$(
)
part of the command is executed by the local shell before it even starts thessh
command. That's true both when$(
)
stands alone as well as when it is enclosed by"
s. However if$(
)
was inside'
s it would not be executed by the local shell.
– kasperd
Dec 3 '18 at 16:07
add a comment |
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 test@192.168.94.139 "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
command-line bash ssh
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 test@192.168.94.139 "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
command-line bash ssh
command-line bash ssh
edited Dec 3 '18 at 10:02
pa4080
13.6k52564
13.6k52564
asked Dec 3 '18 at 3:37
JanithJanith
748
748
Then how can I customize this?
– Janith
Dec 3 '18 at 5:30
@user68186 Why's that? The command is in quotes.
– Lightness Races in Orbit
Dec 3 '18 at 11:12
2
The$(
)
part of the command is executed by the local shell before it even starts thessh
command. That's true both when$(
)
stands alone as well as when it is enclosed by"
s. However if$(
)
was inside'
s it would not be executed by the local shell.
– kasperd
Dec 3 '18 at 16:07
add a comment |
Then how can I customize this?
– Janith
Dec 3 '18 at 5:30
@user68186 Why's that? The command is in quotes.
– Lightness Races in Orbit
Dec 3 '18 at 11:12
2
The$(
)
part of the command is executed by the local shell before it even starts thessh
command. That's true both when$(
)
stands alone as well as when it is enclosed by"
s. However if$(
)
was inside'
s it would not be executed by the local shell.
– kasperd
Dec 3 '18 at 16:07
Then how can I customize this?
– Janith
Dec 3 '18 at 5:30
Then how can I customize this?
– Janith
Dec 3 '18 at 5:30
@user68186 Why's that? The command is in quotes.
– Lightness Races in Orbit
Dec 3 '18 at 11:12
@user68186 Why's that? The command is in quotes.
– Lightness Races in Orbit
Dec 3 '18 at 11:12
2
2
The
$(
)
part of the command is executed by the local shell before it even starts the ssh
command. That's true both when $(
)
stands alone as well as when it is enclosed by "
s. However if $(
)
was inside '
s it would not be executed by the local shell.– kasperd
Dec 3 '18 at 16:07
The
$(
)
part of the command is executed by the local shell before it even starts the ssh
command. That's true both when $(
)
stands alone as well as when it is enclosed by "
s. However if $(
)
was inside '
s it would not be executed by the local shell.– kasperd
Dec 3 '18 at 16:07
add a comment |
4 Answers
4
active
oldest
votes
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 the echo
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.
#!/bin/bash
ssh -t test@192.168.94.139 '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'
This works for me. thanks a lot
– Janith
Dec 4 '18 at 2:26
I want to assign/var/www/test.com/backup
into a variable called "BACKUPDEST" andcd $BACKUPDEST
Can you tell me how to do this?
– Janith
Dec 4 '18 at 2:48
1
Where do you assign the value toBACKUPDEST
? If that happens on the remote side, just include it in the script normally. If you want to set it locally (e.g. calculate it in the local script, or pass it in as a command line argument), you can change the first line to e.g."cd $BACKUPDEST"' ;
- the shell expands the double-quoted part, keeps the single-quoted part intact, concatenates the two and passes the result as the last argument tossh
.
– pt314
Dec 4 '18 at 9:34
Uh, make that"cd '$BACKUPDEST'"' ;
in case the path in that variable contains some weirdness (e.g. a space). Again: just saying that it can be done this way, not that it should be done this way.
– pt314
Dec 4 '18 at 9:46
add a comment |
Yes you can exexute complex scripts via ssh
#!/bin/bash -e
ssh_cmd="$(cat <<-EOF
cd /var/www/test.com/backup;
if [ $(ls | wc -l) -lt 3 ]; then
echo "less"
elif [ $(ls -t *.tgz|awk 'NR >3'|xargs rm -f) ]; then
echo "deleted"
else
echo "something else"
fi
EOF
)"
ssh -t test@192.168.94.139 "$ssh_cmd"
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:
#!/bin/bash -e
tmp_dir="$(mktemp -d)"
ssh_cmd="$(cat <<-EOF
cd "$tmp_dir"
cnt_tgz=($(find . -type f -name "*.tgz"))
if [[ ${#cnt_tgz[@]} -lt 3 ]]; then
echo "less"
else
rm "${cnt_tgz[@]}"
echo "deleted"
fi
EOF
)"
touch "$tmp_dir/1.tgz"
ssh -t localhost "$ssh_cmd"
touch "$tmp_dir/2.tgz" "$tmp_dir/3.tgz"
ssh -t localhost "$ssh_cmd"
The ls -t *.tgz
will not work, since the globbing is only happening on the local system. Also using ls
for counting files is not a good idea, since it also returns entries like .
, ..
and directories.
I got some errors.syntax error near unexpected token elif'
,elif [ $(ls -t |awk 'NR >3'|xargs rm -f) ]; then'
– Janith
Dec 3 '18 at 8:33
There was a;
missing in the fist if-statement. But I did not fix you script! There are many more issues e.g. thels *.tgz
– Simon Sudler
Dec 3 '18 at 9:17
1
"The ls -t *.tgz will not work, since the globbing is only happening on the local system." - it will happen on the remote system if you escape it properly. The original version had naked$(...)
inside a double-quoted string, so the local shell evaluated it. Escaping it as$(...)
as you showed in the first example, or using single quotes around the whole script, prevents the local shell from expanding it, so it gets sent over to the remote system, it is expanded by the remote shell, and the script works as intended.
– pt314
Dec 3 '18 at 12:46
This is the kind of situation where I would highly recommend using single quotes instead of a here document. Even if you have some variables you want to insert, you're better off using a single-quoted string andprintf
to expand variables -- that's still going to be easier to manage than trying to escape all the shell variables throughout. Also, it would avoid needing to usecat
just to capture the here document into a variable!
– Daniel Pryden
Dec 3 '18 at 12:56
add a comment |
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
:
cd /var/www/test.com/backup;
if [ $(ls | wc -l) -lt 3 ]; then
echo "less"
elif [ $(ls -t *.tgz|awk 'NR >3'|xargs rm -f) ]; then
echo "deleted"
else
echo "something else"
fi
Then:
cat myscript.sh |
ssh -t test@192.168.94.139
"cat - > /tmp/ms.sh && sh /tmp/ms.sh && rm /tmp/ms.sh"
Or (avoiding a useless use of cat):
ssh -t test@192.168.94.139
"cat - > /tmp/ms.sh && sh /tmp/ms.sh && rm /tmp/ms.sh"
< myscript.sh
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.
No need to save the script into a temporary file either, just pipe it into a suitable shell, i.e.ssh user@host bash <myscript.sh
.
– pt314
Dec 3 '18 at 14:17
2
Keep in mind, though, that redirection only works when the script itself does not try to read from standard input.
– chepner
Dec 3 '18 at 18:19
@pt314 Yes, but see Pipe a script into bash?
– PerlDuck
Dec 3 '18 at 19:04
Yes, redirection has its limitations. It also avoids a bunch of security issues associated with writing (and then executing) a predictably-named temporary file. If you do use a temporary script (whether by choice or necessity), create it usingmktemp
or something similarly safe.
– pt314
Dec 4 '18 at 9:52
add a comment |
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:
#!/bin/bash
HOST='test@192.168.94.139'
REMOTE_PATH='/var/www/test.com/backup'
COMMAND1="ssh "$HOST" 'ls "$REMOTE_PATH" | wc -l'"
COMMAND2="ssh "$HOST" 'ls -t "$REMOTE_PATH"/*.tgz'"
COMMAND3="xargs ssh "$HOST" rm -rf"
if [[ $(eval "$COMMAND1") -le 3 ]]
then
echo "Less"
else
eval "$COMMAND2" | awk 'NR > 3' | eval "$COMMAND3" && echo "Deleted"
fi
Notes:
- The conditional expression
-lt
is replaced by-le
.
eval
- construct command by concatenating arguments.- I'm not sure do we really need these extra quotations
"
within the$COMMAND{1..3}
expression, but I decide to add them.
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "89"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2faskubuntu.com%2fquestions%2f1098053%2fhow-can-ssh-work-with-an-if-condition%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
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 the echo
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.
#!/bin/bash
ssh -t test@192.168.94.139 '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'
This works for me. thanks a lot
– Janith
Dec 4 '18 at 2:26
I want to assign/var/www/test.com/backup
into a variable called "BACKUPDEST" andcd $BACKUPDEST
Can you tell me how to do this?
– Janith
Dec 4 '18 at 2:48
1
Where do you assign the value toBACKUPDEST
? If that happens on the remote side, just include it in the script normally. If you want to set it locally (e.g. calculate it in the local script, or pass it in as a command line argument), you can change the first line to e.g."cd $BACKUPDEST"' ;
- the shell expands the double-quoted part, keeps the single-quoted part intact, concatenates the two and passes the result as the last argument tossh
.
– pt314
Dec 4 '18 at 9:34
Uh, make that"cd '$BACKUPDEST'"' ;
in case the path in that variable contains some weirdness (e.g. a space). Again: just saying that it can be done this way, not that it should be done this way.
– pt314
Dec 4 '18 at 9:46
add a comment |
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 the echo
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.
#!/bin/bash
ssh -t test@192.168.94.139 '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'
This works for me. thanks a lot
– Janith
Dec 4 '18 at 2:26
I want to assign/var/www/test.com/backup
into a variable called "BACKUPDEST" andcd $BACKUPDEST
Can you tell me how to do this?
– Janith
Dec 4 '18 at 2:48
1
Where do you assign the value toBACKUPDEST
? If that happens on the remote side, just include it in the script normally. If you want to set it locally (e.g. calculate it in the local script, or pass it in as a command line argument), you can change the first line to e.g."cd $BACKUPDEST"' ;
- the shell expands the double-quoted part, keeps the single-quoted part intact, concatenates the two and passes the result as the last argument tossh
.
– pt314
Dec 4 '18 at 9:34
Uh, make that"cd '$BACKUPDEST'"' ;
in case the path in that variable contains some weirdness (e.g. a space). Again: just saying that it can be done this way, not that it should be done this way.
– pt314
Dec 4 '18 at 9:46
add a comment |
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 the echo
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.
#!/bin/bash
ssh -t test@192.168.94.139 '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'
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 the echo
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.
#!/bin/bash
ssh -t test@192.168.94.139 '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'
edited Dec 4 '18 at 9:40
answered Dec 3 '18 at 13:19
pt314pt314
1464
1464
This works for me. thanks a lot
– Janith
Dec 4 '18 at 2:26
I want to assign/var/www/test.com/backup
into a variable called "BACKUPDEST" andcd $BACKUPDEST
Can you tell me how to do this?
– Janith
Dec 4 '18 at 2:48
1
Where do you assign the value toBACKUPDEST
? If that happens on the remote side, just include it in the script normally. If you want to set it locally (e.g. calculate it in the local script, or pass it in as a command line argument), you can change the first line to e.g."cd $BACKUPDEST"' ;
- the shell expands the double-quoted part, keeps the single-quoted part intact, concatenates the two and passes the result as the last argument tossh
.
– pt314
Dec 4 '18 at 9:34
Uh, make that"cd '$BACKUPDEST'"' ;
in case the path in that variable contains some weirdness (e.g. a space). Again: just saying that it can be done this way, not that it should be done this way.
– pt314
Dec 4 '18 at 9:46
add a comment |
This works for me. thanks a lot
– Janith
Dec 4 '18 at 2:26
I want to assign/var/www/test.com/backup
into a variable called "BACKUPDEST" andcd $BACKUPDEST
Can you tell me how to do this?
– Janith
Dec 4 '18 at 2:48
1
Where do you assign the value toBACKUPDEST
? If that happens on the remote side, just include it in the script normally. If you want to set it locally (e.g. calculate it in the local script, or pass it in as a command line argument), you can change the first line to e.g."cd $BACKUPDEST"' ;
- the shell expands the double-quoted part, keeps the single-quoted part intact, concatenates the two and passes the result as the last argument tossh
.
– pt314
Dec 4 '18 at 9:34
Uh, make that"cd '$BACKUPDEST'"' ;
in case the path in that variable contains some weirdness (e.g. a space). Again: just saying that it can be done this way, not that it should be done this way.
– pt314
Dec 4 '18 at 9:46
This works for me. thanks a lot
– Janith
Dec 4 '18 at 2:26
This works for me. thanks a lot
– Janith
Dec 4 '18 at 2:26
I want to assign
/var/www/test.com/backup
into a variable called "BACKUPDEST" and cd $BACKUPDEST
Can you tell me how to do this?– Janith
Dec 4 '18 at 2:48
I want to assign
/var/www/test.com/backup
into a variable called "BACKUPDEST" and cd $BACKUPDEST
Can you tell me how to do this?– Janith
Dec 4 '18 at 2:48
1
1
Where do you assign the value to
BACKUPDEST
? If that happens on the remote side, just include it in the script normally. If you want to set it locally (e.g. calculate it in the local script, or pass it in as a command line argument), you can change the first line to e.g. "cd $BACKUPDEST"' ;
- the shell expands the double-quoted part, keeps the single-quoted part intact, concatenates the two and passes the result as the last argument to ssh
.– pt314
Dec 4 '18 at 9:34
Where do you assign the value to
BACKUPDEST
? If that happens on the remote side, just include it in the script normally. If you want to set it locally (e.g. calculate it in the local script, or pass it in as a command line argument), you can change the first line to e.g. "cd $BACKUPDEST"' ;
- the shell expands the double-quoted part, keeps the single-quoted part intact, concatenates the two and passes the result as the last argument to ssh
.– pt314
Dec 4 '18 at 9:34
Uh, make that
"cd '$BACKUPDEST'"' ;
in case the path in that variable contains some weirdness (e.g. a space). Again: just saying that it can be done this way, not that it should be done this way.– pt314
Dec 4 '18 at 9:46
Uh, make that
"cd '$BACKUPDEST'"' ;
in case the path in that variable contains some weirdness (e.g. a space). Again: just saying that it can be done this way, not that it should be done this way.– pt314
Dec 4 '18 at 9:46
add a comment |
Yes you can exexute complex scripts via ssh
#!/bin/bash -e
ssh_cmd="$(cat <<-EOF
cd /var/www/test.com/backup;
if [ $(ls | wc -l) -lt 3 ]; then
echo "less"
elif [ $(ls -t *.tgz|awk 'NR >3'|xargs rm -f) ]; then
echo "deleted"
else
echo "something else"
fi
EOF
)"
ssh -t test@192.168.94.139 "$ssh_cmd"
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:
#!/bin/bash -e
tmp_dir="$(mktemp -d)"
ssh_cmd="$(cat <<-EOF
cd "$tmp_dir"
cnt_tgz=($(find . -type f -name "*.tgz"))
if [[ ${#cnt_tgz[@]} -lt 3 ]]; then
echo "less"
else
rm "${cnt_tgz[@]}"
echo "deleted"
fi
EOF
)"
touch "$tmp_dir/1.tgz"
ssh -t localhost "$ssh_cmd"
touch "$tmp_dir/2.tgz" "$tmp_dir/3.tgz"
ssh -t localhost "$ssh_cmd"
The ls -t *.tgz
will not work, since the globbing is only happening on the local system. Also using ls
for counting files is not a good idea, since it also returns entries like .
, ..
and directories.
I got some errors.syntax error near unexpected token elif'
,elif [ $(ls -t |awk 'NR >3'|xargs rm -f) ]; then'
– Janith
Dec 3 '18 at 8:33
There was a;
missing in the fist if-statement. But I did not fix you script! There are many more issues e.g. thels *.tgz
– Simon Sudler
Dec 3 '18 at 9:17
1
"The ls -t *.tgz will not work, since the globbing is only happening on the local system." - it will happen on the remote system if you escape it properly. The original version had naked$(...)
inside a double-quoted string, so the local shell evaluated it. Escaping it as$(...)
as you showed in the first example, or using single quotes around the whole script, prevents the local shell from expanding it, so it gets sent over to the remote system, it is expanded by the remote shell, and the script works as intended.
– pt314
Dec 3 '18 at 12:46
This is the kind of situation where I would highly recommend using single quotes instead of a here document. Even if you have some variables you want to insert, you're better off using a single-quoted string andprintf
to expand variables -- that's still going to be easier to manage than trying to escape all the shell variables throughout. Also, it would avoid needing to usecat
just to capture the here document into a variable!
– Daniel Pryden
Dec 3 '18 at 12:56
add a comment |
Yes you can exexute complex scripts via ssh
#!/bin/bash -e
ssh_cmd="$(cat <<-EOF
cd /var/www/test.com/backup;
if [ $(ls | wc -l) -lt 3 ]; then
echo "less"
elif [ $(ls -t *.tgz|awk 'NR >3'|xargs rm -f) ]; then
echo "deleted"
else
echo "something else"
fi
EOF
)"
ssh -t test@192.168.94.139 "$ssh_cmd"
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:
#!/bin/bash -e
tmp_dir="$(mktemp -d)"
ssh_cmd="$(cat <<-EOF
cd "$tmp_dir"
cnt_tgz=($(find . -type f -name "*.tgz"))
if [[ ${#cnt_tgz[@]} -lt 3 ]]; then
echo "less"
else
rm "${cnt_tgz[@]}"
echo "deleted"
fi
EOF
)"
touch "$tmp_dir/1.tgz"
ssh -t localhost "$ssh_cmd"
touch "$tmp_dir/2.tgz" "$tmp_dir/3.tgz"
ssh -t localhost "$ssh_cmd"
The ls -t *.tgz
will not work, since the globbing is only happening on the local system. Also using ls
for counting files is not a good idea, since it also returns entries like .
, ..
and directories.
I got some errors.syntax error near unexpected token elif'
,elif [ $(ls -t |awk 'NR >3'|xargs rm -f) ]; then'
– Janith
Dec 3 '18 at 8:33
There was a;
missing in the fist if-statement. But I did not fix you script! There are many more issues e.g. thels *.tgz
– Simon Sudler
Dec 3 '18 at 9:17
1
"The ls -t *.tgz will not work, since the globbing is only happening on the local system." - it will happen on the remote system if you escape it properly. The original version had naked$(...)
inside a double-quoted string, so the local shell evaluated it. Escaping it as$(...)
as you showed in the first example, or using single quotes around the whole script, prevents the local shell from expanding it, so it gets sent over to the remote system, it is expanded by the remote shell, and the script works as intended.
– pt314
Dec 3 '18 at 12:46
This is the kind of situation where I would highly recommend using single quotes instead of a here document. Even if you have some variables you want to insert, you're better off using a single-quoted string andprintf
to expand variables -- that's still going to be easier to manage than trying to escape all the shell variables throughout. Also, it would avoid needing to usecat
just to capture the here document into a variable!
– Daniel Pryden
Dec 3 '18 at 12:56
add a comment |
Yes you can exexute complex scripts via ssh
#!/bin/bash -e
ssh_cmd="$(cat <<-EOF
cd /var/www/test.com/backup;
if [ $(ls | wc -l) -lt 3 ]; then
echo "less"
elif [ $(ls -t *.tgz|awk 'NR >3'|xargs rm -f) ]; then
echo "deleted"
else
echo "something else"
fi
EOF
)"
ssh -t test@192.168.94.139 "$ssh_cmd"
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:
#!/bin/bash -e
tmp_dir="$(mktemp -d)"
ssh_cmd="$(cat <<-EOF
cd "$tmp_dir"
cnt_tgz=($(find . -type f -name "*.tgz"))
if [[ ${#cnt_tgz[@]} -lt 3 ]]; then
echo "less"
else
rm "${cnt_tgz[@]}"
echo "deleted"
fi
EOF
)"
touch "$tmp_dir/1.tgz"
ssh -t localhost "$ssh_cmd"
touch "$tmp_dir/2.tgz" "$tmp_dir/3.tgz"
ssh -t localhost "$ssh_cmd"
The ls -t *.tgz
will not work, since the globbing is only happening on the local system. Also using ls
for counting files is not a good idea, since it also returns entries like .
, ..
and directories.
Yes you can exexute complex scripts via ssh
#!/bin/bash -e
ssh_cmd="$(cat <<-EOF
cd /var/www/test.com/backup;
if [ $(ls | wc -l) -lt 3 ]; then
echo "less"
elif [ $(ls -t *.tgz|awk 'NR >3'|xargs rm -f) ]; then
echo "deleted"
else
echo "something else"
fi
EOF
)"
ssh -t test@192.168.94.139 "$ssh_cmd"
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:
#!/bin/bash -e
tmp_dir="$(mktemp -d)"
ssh_cmd="$(cat <<-EOF
cd "$tmp_dir"
cnt_tgz=($(find . -type f -name "*.tgz"))
if [[ ${#cnt_tgz[@]} -lt 3 ]]; then
echo "less"
else
rm "${cnt_tgz[@]}"
echo "deleted"
fi
EOF
)"
touch "$tmp_dir/1.tgz"
ssh -t localhost "$ssh_cmd"
touch "$tmp_dir/2.tgz" "$tmp_dir/3.tgz"
ssh -t localhost "$ssh_cmd"
The ls -t *.tgz
will not work, since the globbing is only happening on the local system. Also using ls
for counting files is not a good idea, since it also returns entries like .
, ..
and directories.
edited Dec 3 '18 at 9:46
DevSolar
1436
1436
answered Dec 3 '18 at 8:11
Simon SudlerSimon Sudler
1,451313
1,451313
I got some errors.syntax error near unexpected token elif'
,elif [ $(ls -t |awk 'NR >3'|xargs rm -f) ]; then'
– Janith
Dec 3 '18 at 8:33
There was a;
missing in the fist if-statement. But I did not fix you script! There are many more issues e.g. thels *.tgz
– Simon Sudler
Dec 3 '18 at 9:17
1
"The ls -t *.tgz will not work, since the globbing is only happening on the local system." - it will happen on the remote system if you escape it properly. The original version had naked$(...)
inside a double-quoted string, so the local shell evaluated it. Escaping it as$(...)
as you showed in the first example, or using single quotes around the whole script, prevents the local shell from expanding it, so it gets sent over to the remote system, it is expanded by the remote shell, and the script works as intended.
– pt314
Dec 3 '18 at 12:46
This is the kind of situation where I would highly recommend using single quotes instead of a here document. Even if you have some variables you want to insert, you're better off using a single-quoted string andprintf
to expand variables -- that's still going to be easier to manage than trying to escape all the shell variables throughout. Also, it would avoid needing to usecat
just to capture the here document into a variable!
– Daniel Pryden
Dec 3 '18 at 12:56
add a comment |
I got some errors.syntax error near unexpected token elif'
,elif [ $(ls -t |awk 'NR >3'|xargs rm -f) ]; then'
– Janith
Dec 3 '18 at 8:33
There was a;
missing in the fist if-statement. But I did not fix you script! There are many more issues e.g. thels *.tgz
– Simon Sudler
Dec 3 '18 at 9:17
1
"The ls -t *.tgz will not work, since the globbing is only happening on the local system." - it will happen on the remote system if you escape it properly. The original version had naked$(...)
inside a double-quoted string, so the local shell evaluated it. Escaping it as$(...)
as you showed in the first example, or using single quotes around the whole script, prevents the local shell from expanding it, so it gets sent over to the remote system, it is expanded by the remote shell, and the script works as intended.
– pt314
Dec 3 '18 at 12:46
This is the kind of situation where I would highly recommend using single quotes instead of a here document. Even if you have some variables you want to insert, you're better off using a single-quoted string andprintf
to expand variables -- that's still going to be easier to manage than trying to escape all the shell variables throughout. Also, it would avoid needing to usecat
just to capture the here document into a variable!
– Daniel Pryden
Dec 3 '18 at 12:56
I got some errors.
syntax error near unexpected token elif'
, elif [ $(ls -t |awk 'NR >3'|xargs rm -f) ]; then'
– Janith
Dec 3 '18 at 8:33
I got some errors.
syntax error near unexpected token elif'
, elif [ $(ls -t |awk 'NR >3'|xargs rm -f) ]; then'
– Janith
Dec 3 '18 at 8:33
There was a
;
missing in the fist if-statement. But I did not fix you script! There are many more issues e.g. the ls *.tgz
– Simon Sudler
Dec 3 '18 at 9:17
There was a
;
missing in the fist if-statement. But I did not fix you script! There are many more issues e.g. the ls *.tgz
– Simon Sudler
Dec 3 '18 at 9:17
1
1
"The ls -t *.tgz will not work, since the globbing is only happening on the local system." - it will happen on the remote system if you escape it properly. The original version had naked
$(...)
inside a double-quoted string, so the local shell evaluated it. Escaping it as $(...)
as you showed in the first example, or using single quotes around the whole script, prevents the local shell from expanding it, so it gets sent over to the remote system, it is expanded by the remote shell, and the script works as intended.– pt314
Dec 3 '18 at 12:46
"The ls -t *.tgz will not work, since the globbing is only happening on the local system." - it will happen on the remote system if you escape it properly. The original version had naked
$(...)
inside a double-quoted string, so the local shell evaluated it. Escaping it as $(...)
as you showed in the first example, or using single quotes around the whole script, prevents the local shell from expanding it, so it gets sent over to the remote system, it is expanded by the remote shell, and the script works as intended.– pt314
Dec 3 '18 at 12:46
This is the kind of situation where I would highly recommend using single quotes instead of a here document. Even if you have some variables you want to insert, you're better off using a single-quoted string and
printf
to expand variables -- that's still going to be easier to manage than trying to escape all the shell variables throughout. Also, it would avoid needing to use cat
just to capture the here document into a variable!– Daniel Pryden
Dec 3 '18 at 12:56
This is the kind of situation where I would highly recommend using single quotes instead of a here document. Even if you have some variables you want to insert, you're better off using a single-quoted string and
printf
to expand variables -- that's still going to be easier to manage than trying to escape all the shell variables throughout. Also, it would avoid needing to use cat
just to capture the here document into a variable!– Daniel Pryden
Dec 3 '18 at 12:56
add a comment |
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
:
cd /var/www/test.com/backup;
if [ $(ls | wc -l) -lt 3 ]; then
echo "less"
elif [ $(ls -t *.tgz|awk 'NR >3'|xargs rm -f) ]; then
echo "deleted"
else
echo "something else"
fi
Then:
cat myscript.sh |
ssh -t test@192.168.94.139
"cat - > /tmp/ms.sh && sh /tmp/ms.sh && rm /tmp/ms.sh"
Or (avoiding a useless use of cat):
ssh -t test@192.168.94.139
"cat - > /tmp/ms.sh && sh /tmp/ms.sh && rm /tmp/ms.sh"
< myscript.sh
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.
No need to save the script into a temporary file either, just pipe it into a suitable shell, i.e.ssh user@host bash <myscript.sh
.
– pt314
Dec 3 '18 at 14:17
2
Keep in mind, though, that redirection only works when the script itself does not try to read from standard input.
– chepner
Dec 3 '18 at 18:19
@pt314 Yes, but see Pipe a script into bash?
– PerlDuck
Dec 3 '18 at 19:04
Yes, redirection has its limitations. It also avoids a bunch of security issues associated with writing (and then executing) a predictably-named temporary file. If you do use a temporary script (whether by choice or necessity), create it usingmktemp
or something similarly safe.
– pt314
Dec 4 '18 at 9:52
add a comment |
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
:
cd /var/www/test.com/backup;
if [ $(ls | wc -l) -lt 3 ]; then
echo "less"
elif [ $(ls -t *.tgz|awk 'NR >3'|xargs rm -f) ]; then
echo "deleted"
else
echo "something else"
fi
Then:
cat myscript.sh |
ssh -t test@192.168.94.139
"cat - > /tmp/ms.sh && sh /tmp/ms.sh && rm /tmp/ms.sh"
Or (avoiding a useless use of cat):
ssh -t test@192.168.94.139
"cat - > /tmp/ms.sh && sh /tmp/ms.sh && rm /tmp/ms.sh"
< myscript.sh
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.
No need to save the script into a temporary file either, just pipe it into a suitable shell, i.e.ssh user@host bash <myscript.sh
.
– pt314
Dec 3 '18 at 14:17
2
Keep in mind, though, that redirection only works when the script itself does not try to read from standard input.
– chepner
Dec 3 '18 at 18:19
@pt314 Yes, but see Pipe a script into bash?
– PerlDuck
Dec 3 '18 at 19:04
Yes, redirection has its limitations. It also avoids a bunch of security issues associated with writing (and then executing) a predictably-named temporary file. If you do use a temporary script (whether by choice or necessity), create it usingmktemp
or something similarly safe.
– pt314
Dec 4 '18 at 9:52
add a comment |
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
:
cd /var/www/test.com/backup;
if [ $(ls | wc -l) -lt 3 ]; then
echo "less"
elif [ $(ls -t *.tgz|awk 'NR >3'|xargs rm -f) ]; then
echo "deleted"
else
echo "something else"
fi
Then:
cat myscript.sh |
ssh -t test@192.168.94.139
"cat - > /tmp/ms.sh && sh /tmp/ms.sh && rm /tmp/ms.sh"
Or (avoiding a useless use of cat):
ssh -t test@192.168.94.139
"cat - > /tmp/ms.sh && sh /tmp/ms.sh && rm /tmp/ms.sh"
< myscript.sh
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 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
:
cd /var/www/test.com/backup;
if [ $(ls | wc -l) -lt 3 ]; then
echo "less"
elif [ $(ls -t *.tgz|awk 'NR >3'|xargs rm -f) ]; then
echo "deleted"
else
echo "something else"
fi
Then:
cat myscript.sh |
ssh -t test@192.168.94.139
"cat - > /tmp/ms.sh && sh /tmp/ms.sh && rm /tmp/ms.sh"
Or (avoiding a useless use of cat):
ssh -t test@192.168.94.139
"cat - > /tmp/ms.sh && sh /tmp/ms.sh && rm /tmp/ms.sh"
< myscript.sh
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.
answered Dec 3 '18 at 13:44
PerlDuckPerlDuck
5,74211332
5,74211332
No need to save the script into a temporary file either, just pipe it into a suitable shell, i.e.ssh user@host bash <myscript.sh
.
– pt314
Dec 3 '18 at 14:17
2
Keep in mind, though, that redirection only works when the script itself does not try to read from standard input.
– chepner
Dec 3 '18 at 18:19
@pt314 Yes, but see Pipe a script into bash?
– PerlDuck
Dec 3 '18 at 19:04
Yes, redirection has its limitations. It also avoids a bunch of security issues associated with writing (and then executing) a predictably-named temporary file. If you do use a temporary script (whether by choice or necessity), create it usingmktemp
or something similarly safe.
– pt314
Dec 4 '18 at 9:52
add a comment |
No need to save the script into a temporary file either, just pipe it into a suitable shell, i.e.ssh user@host bash <myscript.sh
.
– pt314
Dec 3 '18 at 14:17
2
Keep in mind, though, that redirection only works when the script itself does not try to read from standard input.
– chepner
Dec 3 '18 at 18:19
@pt314 Yes, but see Pipe a script into bash?
– PerlDuck
Dec 3 '18 at 19:04
Yes, redirection has its limitations. It also avoids a bunch of security issues associated with writing (and then executing) a predictably-named temporary file. If you do use a temporary script (whether by choice or necessity), create it usingmktemp
or something similarly safe.
– pt314
Dec 4 '18 at 9:52
No need to save the script into a temporary file either, just pipe it into a suitable shell, i.e.
ssh user@host bash <myscript.sh
.– pt314
Dec 3 '18 at 14:17
No need to save the script into a temporary file either, just pipe it into a suitable shell, i.e.
ssh user@host bash <myscript.sh
.– pt314
Dec 3 '18 at 14:17
2
2
Keep in mind, though, that redirection only works when the script itself does not try to read from standard input.
– chepner
Dec 3 '18 at 18:19
Keep in mind, though, that redirection only works when the script itself does not try to read from standard input.
– chepner
Dec 3 '18 at 18:19
@pt314 Yes, but see Pipe a script into bash?
– PerlDuck
Dec 3 '18 at 19:04
@pt314 Yes, but see Pipe a script into bash?
– PerlDuck
Dec 3 '18 at 19:04
Yes, redirection has its limitations. It also avoids a bunch of security issues associated with writing (and then executing) a predictably-named temporary file. If you do use a temporary script (whether by choice or necessity), create it using
mktemp
or something similarly safe.– pt314
Dec 4 '18 at 9:52
Yes, redirection has its limitations. It also avoids a bunch of security issues associated with writing (and then executing) a predictably-named temporary file. If you do use a temporary script (whether by choice or necessity), create it using
mktemp
or something similarly safe.– pt314
Dec 4 '18 at 9:52
add a comment |
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:
#!/bin/bash
HOST='test@192.168.94.139'
REMOTE_PATH='/var/www/test.com/backup'
COMMAND1="ssh "$HOST" 'ls "$REMOTE_PATH" | wc -l'"
COMMAND2="ssh "$HOST" 'ls -t "$REMOTE_PATH"/*.tgz'"
COMMAND3="xargs ssh "$HOST" rm -rf"
if [[ $(eval "$COMMAND1") -le 3 ]]
then
echo "Less"
else
eval "$COMMAND2" | awk 'NR > 3' | eval "$COMMAND3" && echo "Deleted"
fi
Notes:
- The conditional expression
-lt
is replaced by-le
.
eval
- construct command by concatenating arguments.- I'm not sure do we really need these extra quotations
"
within the$COMMAND{1..3}
expression, but I decide to add them.
add a comment |
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:
#!/bin/bash
HOST='test@192.168.94.139'
REMOTE_PATH='/var/www/test.com/backup'
COMMAND1="ssh "$HOST" 'ls "$REMOTE_PATH" | wc -l'"
COMMAND2="ssh "$HOST" 'ls -t "$REMOTE_PATH"/*.tgz'"
COMMAND3="xargs ssh "$HOST" rm -rf"
if [[ $(eval "$COMMAND1") -le 3 ]]
then
echo "Less"
else
eval "$COMMAND2" | awk 'NR > 3' | eval "$COMMAND3" && echo "Deleted"
fi
Notes:
- The conditional expression
-lt
is replaced by-le
.
eval
- construct command by concatenating arguments.- I'm not sure do we really need these extra quotations
"
within the$COMMAND{1..3}
expression, but I decide to add them.
add a comment |
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:
#!/bin/bash
HOST='test@192.168.94.139'
REMOTE_PATH='/var/www/test.com/backup'
COMMAND1="ssh "$HOST" 'ls "$REMOTE_PATH" | wc -l'"
COMMAND2="ssh "$HOST" 'ls -t "$REMOTE_PATH"/*.tgz'"
COMMAND3="xargs ssh "$HOST" rm -rf"
if [[ $(eval "$COMMAND1") -le 3 ]]
then
echo "Less"
else
eval "$COMMAND2" | awk 'NR > 3' | eval "$COMMAND3" && echo "Deleted"
fi
Notes:
- The conditional expression
-lt
is replaced by-le
.
eval
- construct command by concatenating arguments.- I'm not sure do we really need these extra quotations
"
within the$COMMAND{1..3}
expression, but I decide to add them.
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:
#!/bin/bash
HOST='test@192.168.94.139'
REMOTE_PATH='/var/www/test.com/backup'
COMMAND1="ssh "$HOST" 'ls "$REMOTE_PATH" | wc -l'"
COMMAND2="ssh "$HOST" 'ls -t "$REMOTE_PATH"/*.tgz'"
COMMAND3="xargs ssh "$HOST" rm -rf"
if [[ $(eval "$COMMAND1") -le 3 ]]
then
echo "Less"
else
eval "$COMMAND2" | awk 'NR > 3' | eval "$COMMAND3" && echo "Deleted"
fi
Notes:
- The conditional expression
-lt
is replaced by-le
.
eval
- construct command by concatenating arguments.- I'm not sure do we really need these extra quotations
"
within the$COMMAND{1..3}
expression, but I decide to add them.
edited Dec 3 '18 at 10:14
answered Dec 3 '18 at 9:51
pa4080pa4080
13.6k52564
13.6k52564
add a comment |
add a comment |
Thanks for contributing an answer to Ask Ubuntu!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2faskubuntu.com%2fquestions%2f1098053%2fhow-can-ssh-work-with-an-if-condition%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Then how can I customize this?
– Janith
Dec 3 '18 at 5:30
@user68186 Why's that? The command is in quotes.
– Lightness Races in Orbit
Dec 3 '18 at 11:12
2
The
$(
)
part of the command is executed by the local shell before it even starts thessh
command. That's true both when$(
)
stands alone as well as when it is enclosed by"
s. However if$(
)
was inside'
s it would not be executed by the local shell.– kasperd
Dec 3 '18 at 16:07