Repository: ktbyers/netmiko

Issue:
[2.1.1] BaseFileTransfer._remote_file_size_unix() seems to incorrectly parse ls -l output
Hi,

First, thanks for creating and maintaining a great library that is doing a lot of work for us. It's really awesome :-) 

I had an issue doing a file_transfer() to retrieve a remote file, using a linux connection. (version/platform details at bottom of this post)

```
from netmiko import ConnectHandler, file_transfer
client = ConnectHandler(device_type='linux')  # other args ommitted
src = 'remote_dir/export.tar.gz'
dst = 'test_export.tar.gz'
direction = 'get'
res = file_transfer(client, source_file=src, dest_file=dst, direction=direction)
```

This gave the following traceback;

```
/home/proj/test_venv/lib/python3.6/site-packages/netmiko/scp_functions.py in file_transfer(ssh_conn, source_file, dest_file, file_system, direction, disable_md5, inline_transfer, overwrite_file)
     68
---> 69     with TransferClass(**scp_args) as scp_transfer:
     70         if scp_transfer.check_file_exists():

/home/proj/test_venv/lib/python3.6/site-packages/netmiko/ssh_dispatcher.py in FileTransfer(*args, **kwargs)
    208     FileTransferClass = FILE_TRANSFER_MAP[device_type]
--> 209     return FileTransferClass(*args, **kwargs)

/home/proj/test_venv/lib/python3.6/site-packages/netmiko/linux/linux_ssh.py in __init__(self, ssh_conn, source_file, dest_file, file_system, direction)
    113                                                        file_system=file_system,
--> 114                                                        direction=direction)
    115

/home/proj/test_venv/lib/python3.6/site-packages/netmiko/scp_handler.py in __init__(self, ssh_conn, source_file, dest_file, file_system, direction)
     77             self.source_md5 = self.remote_md5(remote_file=source_file)
---> 78             self.file_size = self.remote_file_size(remote_file=source_file)
     79         else:

/home/proj/test_venv/lib/python3.6/site-packages/netmiko/linux/linux_ssh.py in remote_file_size(self, remote_cmd, remote_file)
    125         """Get the file size of the remote file."""
--> 126         return self._remote_file_size_unix(remote_cmd=remote_cmd, remote_file=remote_file)
    127

/home/proj/test_venv/lib/python3.6/site-packages/netmiko/scp_handler.py in _remote_file_size_unix(self, remote_cmd, remote_file)
    227         self.ssh_ctl_chan._return_cli()
--> 228         return int(file_size)
    229

ValueError: invalid literal for int() with base 10: 'file'
```

Replicating the remote-file-size check in https://github.com/ktbyers/netmiko/blob/master/netmiko/scp_handler.py#L221 it appears that the regex also matches error output when the file is not found:
```
In [60]: remote_out
Out[60]: 'ls: /var/tmp/remote_dir/export.tar.gz: No such file or directory'

In [61]: match = re.search(pattern, remote_out, flags=re.M)

In [62]: match.group(0)
Out[62]: 'ls: /var/tmp/remote_dir/export.tar.gz: No such file or directory'
```

In my case, the fix was simple - specify the correct directory in`file_system` parameter to file_transfer:
```
from netmiko import ConnectHandler, file_transfer
client = ConnectHandler(device_type='linux')  # other args ommitted
src = 'remote_dir/export.tar.gz'
dst = 'test_export.tar.gz'
direction = 'get'
file_system = '/home/_nonlocl'
res = file_transfer(client, source_file=src, dest_file=dst, direction=direction, file_system=file_system)
```

The file transfer works now, although I'm getting a "MD5 failure between source and destination files", but that's offtopic.


A better error handling/message in _remote_file_size_unix would be helpful in my opinion.
If you take pull-requests I can try writing one up - although I might not be aware of the impact of changing this low-level function.



**Machine running netmiko**
OS: Debian 9 i686
Netmiko: 2.1.1
Python: 3.6.4

**Target machine**
OS: Check Point Gaia R80.10


Discussion:

Resolving patch:
diff --git a/netmiko/scp_handler.py b/netmiko/scp_handler.py
--- a/netmiko/scp_handler.py
+++ b/netmiko/scp_handler.py
@@ -232,6 +232,11 @@ def _remote_file_size_unix(self, remote_cmd="", remote_file=None):
 
         self.ssh_ctl_chan._enter_shell()
         remote_out = self.ssh_ctl_chan.send_command(remote_cmd, expect_string=r"[\$#]")
+        self.ssh_ctl_chan._return_cli()
+
+        if "No such file or directory" in remote_out:
+            raise IOError("Unable to find file on remote system")
+
         escape_file_name = re.escape(remote_file)
         pattern = r"^.* ({}).*$".format(escape_file_name)
         match = re.search(pattern, remote_out, flags=re.M)
@@ -239,9 +244,11 @@ def _remote_file_size_unix(self, remote_cmd="", remote_file=None):
             # Format: -rw-r--r--  1 pyclass  wheel  12 Nov  5 19:07 /var/tmp/test3.txt
             line = match.group(0)
             file_size = line.split()[4]
+            return int(file_size)
 
-        self.ssh_ctl_chan._return_cli()
-        return int(file_size)
+        raise ValueError(
+            "Search pattern not found for remote file size during SCP transfer."
+        )
 
     def file_md5(self, file_name):
         """Compute MD5 hash of file."""


Test patch: