39
votes

I would like to check if a certain file exists on the remote host. I tried this:

$ if [ ssh user@localhost -p 19999 -e /home/user/Dropbox/path/Research_and_Development/Puffer_and_Traps/Repeaters_Network/UBC_LOGS/log1349544129.tar.bz2 ] then echo "okidoke"; else "not okay!" fi
-sh: syntax error: unexpected "else" (expecting "then") 
12
You're trying to execute that file...Marc B
In general, you need a semi-colon before then: if cmd; then cmd; else cmd; fiWilliam Pursell

12 Answers

51
votes

Here is a simple approach:

#!/bin/bash
USE_IP='-o StrictHostKeyChecking=no username@192.168.1.2'

FILE_NAME=/home/user/file.txt

SSH_PASS='sshpass -p password-for-remote-machine'

if $SSH_PASS ssh $USE_IP stat $FILE_NAME \> /dev/null 2\>\&1
            then
                    echo "File exists"
            else
                    echo "File does not exist"

fi

You need to install sshpass on your machine to work it.

53
votes

In addition to the answers above, there's the shorthand way to do it:

ssh -q $HOST [[ -f $FILE_PATH ]] && echo "File exists" || echo "File does not exist";

-q is quiet mode, it will suppress warnings and messages.

As @Mat mentioned, one advantage of testing like this is that you can easily swap out the -f for any test operator you like: -nt, -d, -s etc...

Test Operators: http://tldp.org/LDP/abs/html/fto.html

43
votes

Can't get much simpler than this :)

ssh host "test -e /path/to/file"
if [ $? -eq 0 ]; then
    # your file exists
fi

As suggested by dimo414, this can be collapsed to:

if ssh host "test -e /path/to/file"; then
    # your file exists
fi
12
votes

one line, proper quoting

ssh remote_host test -f "/path/to/file" && echo found || echo not found
7
votes

You're missing ;s. The general syntax if you put it all in one line would be:

if thing ; then ... ; else ... ; fi

The thing can be pretty much anything that returns an exit code. The then branch is taken if that thing returns 0, the else branch otherwise.

[ isn't syntax, it's the test program (check out ls /bin/[, it actually exists, man test for the docs – although can also have a built-in version with different/additional features.) which is used to test various common conditions on files and variables. (Note that [[ on the other hand is syntax and is handled by your shell, if it supports it).

For your case, you don't want to use test directly, you want to test something on the remote host. So try something like:

if ssh user@host test -e "$file" ; then ... ; else ... ; fi
3
votes
ssh -q $HOST [[ -f $FILE_PATH ]] && echo "File exists"

The above will run the echo command on the machine you're running the ssh command from. To get the remote server to run the command:

ssh -q $HOST "[[ ! -f $FILE_PATH ]] && touch $FILE_PATH"
3
votes

Test if a file exists:

HOST="example.com"
FILE="/path/to/file"

if ssh $HOST "test -e $FILE"; then
    echo "File exists."
else
    echo "File does not exist."
fi

And the opposite, test if a file does not exist:

HOST="example.com"
FILE="/path/to/file"

if ! ssh $HOST "test -e $FILE"; then
    echo "File does not exist."
else
    echo "File exists."
fi
1
votes

You can specify the shell to be used by the remote host locally.

echo 'echo "Bash version: ${BASH_VERSION}"' | ssh -q localhost bash

And be careful to (single-)quote the variables you wish to be expanded by the remote host; otherwise variable expansion will be done by your local shell!

# example for local / remote variable expansion
{
echo "[[ $- == *i* ]] && echo 'Interactive' || echo 'Not interactive'" | 
    ssh -q localhost bash
echo '[[ $- == *i* ]] && echo "Interactive" || echo "Not interactive"' | 
    ssh -q localhost bash
}

So, to check if a certain file exists on the remote host you can do the following:

host='localhost'  # localhost as test case
file='~/.bash_history'
if `echo 'test -f '"${file}"' && exit 0 || exit 1' | ssh -q "${host}" sh`; then
#if `echo '[[ -f '"${file}"' ]] && exit 0 || exit 1' | ssh -q "${host}" bash`; then
   echo exists
else
   echo does not exist
fi
0
votes

I wanted also to check if a remote file exist but with RSH. I have tried the previous solutions but they didn't work with RSH.

Finally, I did I short function which works fine:

function existRemoteFile ()
{
REMOTE=$1
FILE=$2
RESULT=$(rsh -l user $REMOTE  "test -e $FILE && echo \"0\" || echo \"1\"")
if [ $RESULT -eq 0 ]
then
    return 0
else
    return 1
fi
}
0
votes

On CentOS machine, the oneliner bash that worked for me was:

if ssh <servername> "stat <filename> > /dev/null 2>&1"; then echo "file exists"; else echo "file doesnt exits"; fi

It needed I/O redirection (as the top answer) as well as quotes around the command to be run on remote.

-1
votes

This also works :

if ssh user@ip "[ -s /path/file_name ]" ;then 
  status=RECEIVED ; 
 else 
  status=MISSING ; 
 fi
-1
votes
#its simple

if [[ "`ssh -q user@hostname ls /dir/filename.abc 2>dev/null`" == "/dir/filename.abc" ]]
then
    echo "file exists"
else
    echo "file not exists"
fi