Getting hostname using ssh

I am writing a script and need to get the hostname of the remote server in order to zip that file... the syntax in which the file is named is "hostname.html."
This is the line I am trying to use

ssh $host "/bin/gzip /tmp/`hostname`.html" >> $PATH_TMP/Linux_cfg2html.log

but whenever I run it `hostname` is replaced for the value in my local server and not the remote server, how can I fix this.

Try this:

ssh "$host" '/bin/gzip /tmp/"$(hostname)".html' >> "$PATH_TMP"/Linux_cfg2html.log

If you're using the old Bourne shell:

ssh "$host" '/bin/gzip /tmp/`hostname`.html' >> "$PATH_TMP"/Linux_cfg2html.log
1 Like

excellent, I will consider single quotes next time, thank you!!

---------- Post updated at 12:10 PM ---------- Previous update was at 11:37 AM ----------

what about the syntax for this line...

scp -p $host:/tmp/`hostname`.html.gz $PATH_TMP/servers/Linux/ >> $PATH_TMP/Linux_cfg2html.log

where I need `hostname` to be the remote hostname, I am getting the same problem of the local value.
Thanks

scp is not a shell, it won't work that way. scp doesn't print files to standard output, either.

There's the old trick of ssh cat filename > localfile though:

Try

ssh username@host 'cat /tmp/`hostname`.html.gz' > /path/to/local/file

Single quotes are to prevent ` from being evaulated in your local shell. One layer of quotes gets stripped off when you ssh, so it gets it without.

that is not what i want to do...

I know the name and format of the file i need scp because I am copying that file from the remote server to my local server, that is why I am using scp.

I need the value of "hostname" because that is the name of the file (server1.html)

If not how can I get the hostname of the remote server and store it in a variable so that I can use it locally on my script.

No you don't. You know the server knows, but scp doesn't run commands on the server so it can't figure out what `hostname` means. It can't do that because scp is not a shell.

You can copy a file with ssh, using the trick I showed you. cat will spew the file to standard output on the remote host -- which goes into the ssh connection. Travelling across the ssh connection, it returns to your local machine -- where you can redirect it into a local file. This works fine even for binary files.

ssh username@host 'cat /path/to/remote/file' > /path/to/local/file

You can also do more elaborate piping to transfer multiple files with permissions:

ssh username@host 'tar -cf - /path/to/remote/files' | tar -xf - -C /path/to/local/dir/

What are you trying to do? You already know the hostname... you use it to connect to the host.

scp -p $host:/tmp/$host.html.gz ...

Just curious: why don't you use the hostname used for the scp connection? Is it different from the machine's hostname output?

scp -p "$host:/tmp/$host.html.gz" ...

Ooops, I just saw that Scott had already asked the same question :slight_smile:

I dont want to redirect the name to a local file, otherwise I would've done it.

How can I save the output of a command to a local variable in my script, not to a local file?

---------- Post updated at 12:29 PM ---------- Previous update was at 12:28 PM ----------

my host is server1
my hostname includes the domain.... server1.domain.com

Same way you do it any other time.

VAR=$(ssh username@host 'cat /tmp/$(hostname).gz')

I don't think this will work for scp, because I see no way to make it print the retrieved file into standard output. again, scp is not a shell.

my host is server1
my hostname includes the domain.... server1.domain.co

I understand, and what's the problem with the solution(s) provided by Corona688?

Then, just: scp $host:/tmp/$host.*.whatever ...

There's surely only one file on each host you want that matches that?

yes of course, that is the workaround, but what if for some reason, the hostname does not come out with the domain name...then the script will fail!! :slight_smile:

---------- Post updated at 12:40 PM ---------- Previous update was at 12:38 PM ----------

that is why i want to store the vale of the command "hostname" of the remote server on my script, because that way I know for sure that the file is named with that same name. does that makes sense?

Sorry, my mistake!

scp $host:/tmp/$host*.whatever ...

Or change whatever generates the file to give it a consistent filename.

hostname -s, or hostname -f, for example.

I guess everything depends where the value of $host comes from. A name server? /etc/hosts?

this is the problem with coronas solution...

REMOTE_FILE=$(ssh $host 'cat /tmp/$(hostname).html.gz')
�B���KH5�/�cpe��}��A����p�LL�;�Lf�IQ>�sz���\Ss�d�
                                               ���C�ov{����ta����}@HxN�Y�*���I�
�mr%v4�1�&5mh�@�o��
(Ƶ=e-�M!��\q�ж��-�4!EyR�d':��_�pqy?��I� ����K?���5�q?���է�5��^ϳ��-F����O��
�<7�aM{ǧ
�� �I�+B��6��@S�]���举�ewh�#X�r)�<���6��l�T A�y�R��<V�Om�"N7e5��d�.��"�r����[`�YJI*�ww^�.�%
          S.Ρ�*�LĪ%����}����z�rJ>��H�Q��2ʯ1�>,�I +��m���8mAJ�s8)���i�%M*��@�y�l`�R�B�LDD��tG"8=���_h+�6ѱ�X���%�b/[K�?xִ7R;/i�0�F:8�WN*H*�#j^v* �t5Ϲ)ɪ���-x�=��By)M�j�Mlp�CҩxHN!�ۼT(�0��"��/Kf{XYq!c��J��,�X<c54,9���� ,r~ f<o1��ǰ�ks0X�nH]�kf DpY&"m>4�tW7�� ��z�J,
                                      � ]I�(^��K�`/6��@^l��o=�dln�aM8���;h��>lj��Aa����ѧv��f�fS�T�WlRY?YH8�Vtr{fP���o��

That's not a problem.

It just went to the screen instead of to a file.

If you had directed it to a file (also as Corona suggested), everything would be just fine.

ssh ...... > $host.html.gz

the value of $host comes from a file that has names of servers..ie
server1
server1
server3

this is my whole script

for host in `cat $PATH_TMP/servers/host_linux2_test`
    do        
        echo "----------------    RUNNING HEALTH CHECK FOR $host   ----------------" >> $PATH_TMP/Linux_cfg2html.log        
        ssh $host "cfg2html-linux -xApo /tmp/" >> $PATH_TMP/Linux_cfg2html.log
        echo "*****************    COMPRESSING FILE in $host   *********************" >> $PATH_TMP/Linux_cfg2html.log
        ssh "$host" '/bin/gzip /tmp/"$(hostname)".html' >> "$PATH_TMP"/Linux_cfg2html.log
        echo "*****************    COPYING FILE TO harp   *********************" >> $PATH_TMP/Linux_cfg2html.log
        scp -p $host:/tmp/"$(hostname)".html.gz $PATH_TMP/servers/Linux/ >> $PATH_TMP/Linux_cfg2html.log
        echo "*****************    REMOVING FILES from $host   *********************" >> $PATH_TMP/Linux_cfg2html.log
        ssh $host "rm -fr /tmp/`hostname`*" >> $PATH_TMP/Linux_cfg2html.log
        echo "----------------------------    DONE    -----------------------------" >> $PATH_TMP/Linux_cfg2html.log
        echo >> $PATH_TMP/Linux_cfg2html.log
    done

and the line i am getting problem is this one...

scp -p $host:/tmp/"$(hostname)".html.gz $PATH_TMP/servers/Linux/ >> $PATH_TMP/Linux_cfg2html.log

because as corona mentioned, scp cannot execute a command, but my file is named in this syntax "server1.domain.com.html.gz" but if for any reason the vaule of hostname on a server does not contain the domain name, then the file would change.. so i cant put the "domain.com" as a hard value . I hope this explains a bit more.

Have you even tried anything I've suggested? They do what you want, even though that changes every other post.

If your script is getting complicated enough, you might want to avoid doing multiple ssh and scp things per server -- that can take a long time -- by combining it all into one script which gets sent to the server. ssh lets you run entire scripts on the remote server easily enough.

ssh username@host exec /bin/sh -s arg1 arg2 < local-file.sh

will act like you've ran local-file.sh on the remote host, with the arguments arg1 arg2 . If you need to pass strings from the local system to the remote one, the arguments are the place to do it. It will print stream data to stdout as usual, which can be redirected in the ways I've already shown you into a local file, or multiple local files, or a local variable.

$ cat script.sh
#!/bin/sh

echo Remote hostname is `hostname`
echo Arguments are $*
exit 0
$ ssh username@server exec /bin/sh -s $HOSTNAME qwertyuipo < script.sh
Remote hostname is steward
Arguments are localname qwertyuipo
$

---------- Post updated at 12:10 PM ---------- Previous update was at 11:49 AM ----------

useless use of cat, and useless use of backticks. We've got to discover who keeps teaching this to people.

You also don't need to reopen the logfile n+1 separate times, you can just redirect the entire loop's output once.

while read host
    do        
        echo "----------------    RUNNING HEALTH CHECK FOR $host   ----------------"        
        ssh $host "cfg2html-linux -xApo /tmp/"
        echo "*****************    COMPRESSING FILE in $host   *********************"
        ssh "$host" '/bin/gzip /tmp/"$(hostname)".html'
        echo "*****************    COPYING FILE TO harp   *********************"
        ssh $host 'cat /tmp/"$(hostname)".html.gz' > $PATH_TMP/servers/Linux/$host.html.gz
        echo "*****************    REMOVING FILES from $host   *********************"
        ssh $host "rm -fr /tmp/`hostname`*"
        echo "----------------------------    DONE    -----------------------------"
        echo
    done < $PATH_TMP/servers/host_linux2_test  >> $PATH_TMP/Linux_cfg2html.log

And as I suspected, you're doing four ssh/scp things per loop which won't break it, but is going to make the script very slow; and causes all the problems you've been struggling with, like the inability to have a local variable on the remote server. I'd suggest a script like this instead:

while read host
    do
            # Here-document is an alternative to feeding it a script file
            # Everything between <<"EOF" and EOF gets fed into the remote host's shell.
            #
            # the script creates the html, and compresses it to stdout.
            # we take stdout and put it into ${host}-config.gz
            # we take stderr and put it into the log file, >&1
            ssh $host exec /bin/sh -s $HOSTNAME 2>&1 > ${host}-config.html.gz <<"EOF"
                # If you echo anything here, send it into >&2, i.e. stderr
                echo "----------------    RUNNING HEALTH CHECK FOR $HOSTNAME   ----------------" >&2
                echo "----------------    (Remote host is $1)   ----------------" >&2
                # Everything in this block gets sent literally.  $(hostname) is remote.
                cfg2html-linux -xApo /tmp/
                # gzip to standard output, instead of resaving to file.gz
                # standard output goes across the ssh connection and is saved into ${host}-config.html.gz
                /bin/gzip - < /tmp/"$(hostname)".html
                rm -f /tmp/$(hostname).html
# MUST be at the beginning of the line.  Do not indent!
EOF

    done < $PATH_TMP/servers/host_linux2_test  >> $PATH_TMP/Linux_cfg2html.log

Everything red is run only on the remote host. The green highlights how I'm getting the local HOSTNAME into the remote $1. (HOSTNAME is a variable that gets set for you by your shell.)

---------- Post updated at 12:29 PM ---------- Previous update was at 12:10 PM ----------

Okay I'm really done editing it now I think:wall:

1 Like

The idea of waht I want to do is there..

However, when I try tu unzip the file (gzip -d ) i am getting this error...

gzip: scxcdb4-config.html.gz: not in gzip format