I am stuck with this piece of code here
user@server:~$ TEST="ssh [email protected] 'date; hostname -A; uname -a'"
user@server:~$ $TEST
bash: date; hostname -A; uname -a: Command not found.
I want to use this inside a shell script an don't know what s the problem. Both systems are debian wheezy,
but if execute the command directly:
user@server:~$ ssh [email protected] 'date; hostname -A; uname -a'
Fre Aug 23 20:02:55 CEST 2013
otherserver.example.org
Linux otherserver 3.2.0-4-amd64 #1 SMP Debian 3.2.46-1 x86_64 GNU/Linux
So whats the big deal here???? I relay am missing out something very trivial, but just cant figure it out... Please help...
The idea behind this, is that i build up a long string inside a script and execute it remotely in a single SSH session (renaming of zfs snapshots all in a row n.0 becomes n.1 and so on)
But its not working a is want it to work...
EDIT/UPDATE: Updated the exaples for beeter understanding of my question (from 'date; date; date' TO 'date; hostname -A; uname -a')
Thanks for all the responses so far. At first eval works but seems to be deprecated as mentioned by Users. So its my job to figure it out again on how to change it.
The string witch hast so be built looks something like this:
echo "Rearanging snapshots..."
last_backup=7
first_backup=0
RENAME_STRING="'sudo zfs destroy $BACKUP_DATASTORE@n.$last_backup; "
while [ $last_backup -gt $first_backup ]
do
RENAME_STRING=$RENAME_STRING"sudo zfs rename $BACKUP_DATASTORE@n.$(($last_backup - 1)) $BACKUP_DATASTORE@n.$last_backup"
if [ $(($last_backup - 1 )) -gt $first_backup ]
then
RENAME_STRING=$RENAME_STRING"; "
else
RENAME_STRING=$RENAME_STRING"'"
fi
last_backup=$(($last_backup - 1 ))
done
#CURRENTLY SOLVED WITH EVAL as this one doesn't work...
#remote_cmd=(/usr/bin/ssh "$BACKUP_USER@$HOST_TO" "$RENAME_STRING")
#"${remote_cmd[@]}"
eval /usr/bin/ssh $BACKUP_USER@$HOST_TO $RENAME_STRING
So maybe you guys will have a more elegant way to solve this?
EDIT2:
Is this output "OK"? (OK as in the means of NOT deprecated, and good to work with?
user@server:~$ TEST="date ; hostname -A ; uname -a"
user@server:~$ ssh [email protected] <<< "$(printf '%s ' $TEST)"
Pseudo-terminal will not be allocated because stdin is not a terminal.
Linux otherserver 3.2.0-4-amd64 #1 SMP Debian 3.2.46-1 x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Fre Aug 23 20:13:53 CEST 2013
otherserver.example.org
Linux otherserver 3.2.0-4-amd64 #1 SMP Debian 3.2.46-1 x86_64 GNU/Linux
EDI3: Updated/improved (?) while loop eval still used as <<< wont work in the script...
The suggested way to execute local commands remotely via ssh is not to use eval. This is discouraged. Since you are storing the whole line in a variable, instead you could
Eval should only be used in legacy systems who do not provide safe tools like the example I'm showing you.
This produces exactly the same result as you were running these commands using the interactive shell.
Hope it gives you some ideas at least.
UPDATE to demonstrate how commands can run remotely too, without defining a local var.
Try shell/bash build-in eval command:
There is no reason to compose such a long string of commands to run via SSH. Just make a permanent script on the remote host called
/usr/local/sbin/rotate_backups
and call it withssh $USER@$HOST 'sudo /usr/local/sbin/rotate_backups'
.If you were asking this on the "Unix & Linux" StackExchange, then this could be an interesting question. However, as a System Administrator, your goals should be maintainability and security. If you are having trouble understanding your script, your colleagues and successors will curse you.
Try this:
It creates an array and executes it as suggested in BashFAQ/050 item 3.
PROBLEM FOUND
I started my long string of with a singe
'
and endet with a single'
NOW i keep all thos single quotes (
'
) by myself create the string and add a double quote at the end, an ALL WORKS!So can someone explain this to me, why i can not set the quotes Inside my Variable?
And this construct now works just fine. Thank you all for your help! I hope that my answer will also help someone! (the ALL_CAPITAL thing will be sorted out later ;) )