We help IT Professionals succeed at work.

How can I determine missing excape characters from current string command from master to remote server via SSH?

I am running into issue to determine escape characters from master to remote server over ssh.  I can return desired output on remote server with no issues.  Trying to run similar string on master server to remote server to get same result.

Below example is working fine on remote server and has expected results:

[root@remote_server ~]# echo ${passwd_expire}
Jun 17, 2020
[root@remote_server ~]# echo ${current_date}
Jan 09, 2020
[root@remote_server ~]# echo $(( ($(date --date="$(echo ${passwd_expire})" +%s) - $(date --date="$(echo ${current_date})" +%s) )/(60*60*24) ))
159

Open in new window


I would like to run those remotely and get same output, but I keep running into bash errors and I can't determine which escape character I could be missing or if it's execution process order is incorrect.

server=remote_server


[root@master ~]# echo ${passwd_expire}
Jun 17, 2020
[root@master ~]# echo ${current_date}
Jan 09, 2020
[root@master ~]# ssh -q ${server} "echo $(( ($(date --date="$(echo ${passwd_expire})" +%s) - $(date --date="$(echo ${current_date})" +%s) )/(60*60*24) ))"

Open in new window


Need some advice on how I can run similar string directly on remote server on this master server as well via ssh.
Comment
Watch Question

Kent OlsenData Warehouse / Database Architect

Commented:
Hi AXI25,

If either {current_date} or {passwd_expire} is blank, you'll get an empty substitution and the date function won't work.  Are you sure that they're set on the remote server?

Run the command through "echo" to see what text will be executed.

 echo ${server} "echo $(( ($(date --date="$(echo ${passwd_expire})" +%s) - $(date --date="$(echo ${current_date})" +%s) )/(60*60*24) ))"

Try with the variables set and empty to see the difference.

Author

Commented:
Hello Kent,

In my original entry, I show the output for the variables are set and not zero/blank. Below you can see more detailed output.

[root@master ~]# echo ${passwd_expire}
Jun 17, 2020
[root@master ~]# echo ${current_date}
Jan 09, 2020

Open in new window


When running through echo, i know I can see it's missing an escape or subshell psossible. I'm getting the below output.

root@master]#  echo ${server} "echo $(( ($(date --date="$(echo ${passwd_expire})" +%s) - $(date --date="$(echo ${current_date})" +%s) )/(60*60*24) ))"
date: illegal option -- date=Jun 17, 2020
usage:  date [-u] mmddHHMM[[cc]yy][.SS]
        date [-u] [+format]
        date -a [-]sss[.fff]
date: illegal option -- date=Jan 09, 2020
usage:  date [-u] mmddHHMM[[cc]yy][.SS]
        date [-u] [+format]
        date -a [-]sss[.fff]
bash: ( -  )/(60*60*24) : syntax error: operand expected (error token is ")/(60*60*24) ")

Open in new window

Kent OlsenData Warehouse / Database Architect

Commented:
The date command in AIX is much more limited that date on other systems.

I can't get it to execute on my local AIX system, much less a remote one.  I'm getting the same errors that you are.  The date function is the culprit.
Kent OlsenData Warehouse / Database Architect

Commented:
The date command in AIX will set the date, or display the current date in any of many formats.

You cannot pass a date value to the date command and have it reformat it.  That appears to be what you're trying to do.

Author

Commented:
On this particular example I am currently testing this on Redhat Linux, but same errors as you're pointing out. I was able to run just the reformat portion also remotely, that wasn't an issue, when trying to narrow it down.  It appears when I try to calculate the delta and the arithmetic portion it's clobbering out. I can get the date format returned fine.  What I will try next is either running a script local to the remote server and then copy data back. Or, I'll try to collect the dates locally on the master server and do the arithmetic there.

It would be nice to have it done through one SSH string command, but I have other methods that seem to be working.
Kent OlsenData Warehouse / Database Architect

Commented:
Ahhh....

Based on your user I assumed that this was an AIX issue.  :)
ssh does not provide a command interpreter and additionally your $() stuff will be executed locally.

simplest way is the following :

echo '$(( ($(date --date="$(echo ${passwd_expire})" +%s) - $(date --date="$(echo ${current_date})" ' | ssh TARGET sh -s

or maybe

ssh TARGET sh -c 'echo $(( ($(date --date="$(echo ${passwd_expire})" +%s) - $(date --date="$(echo ${current_date})"'

... i really recommend the first variant whenever the command is even mildly complex. and it also allows to pipe in complete multiline  scripts

ssh TARGET <<'EOF'
echo $(( ($(date --date="$(echo ${passwd_expire})" +%s) - $(date --date="$(echo ${current_date})"
EOF

additional bonus : you can use both quotes and double quotes without bothering

Author

Commented:
Thank you, both. As I didn't create my script as mentioned by skullnobrains, I was still running into same issue, it did make sense that it's running command locally.  What I ended up doing as example to work was the idea of it running it remotely as a whole script instead of it remotely through SSH. Collects the data on the remote server and just copies it back to master.  It's running over 500 plus servers and doing it as multi-threaded.

#!/bin/bash
# This is local script on master server

<code>

scp /var/tmp/remote_script.bsh remote_server:/var/tmp/

<code>

ssh remote_server "/var/tmp/remote_script.bsh"

<code>

scp -p remote_script:/var/tmp/remote_output.txt /var/tmp/

exit
i recommend you use the last variant i gave you. It pipes the  command directly into the remote shell which is both more efficient and more secure.

Quoting the 'EOF' ensures nothing is interpreted locally and the script is xferred exactly as typed.

I used this method with complex scripts very extensively in the past years. The return code is also transmitted properlt by ssh.