Closed delica1 closed 5 years ago
Hi there,
Thanks for the interest. What is different about opening a file? Even special files are used like regular files on posix systems, so what else other than cat <file>
and .write
on the channel would be needed for a specific example? PR welcome if there is anything unique about this.
Paramiko for example is not able to open a FIFO pipe on Solaris for writing (via SFTP). Trying to do it always raises an OSError or IOError. I was hoping I would be able to do this with ssh2-python.
Short answer is try it and find out. What other libraries do or do not do is not relevant to this one.
Don't see anything special needed here - if there is some issue then can re-open with code to reproduce.
Just tried it using the sftp example you provide. First issue is that LIBSSH2_FXF_APPEND
is not implemented, so I cannot append to the input pipe, only write. The second and more serious problem is that I can open the FIFO pipe but cannot write anything to it. Any attempt to write throws an SFTPProtocolError
. Writing to normal text files works fine.
import socket
from ssh2.session import Session
from ssh2.sftp import LIBSSH2_FXF_CREAT, LIBSSH2_FXF_WRITE, \
LIBSSH2_SFTP_S_IRUSR, LIBSSH2_SFTP_S_IRGRP, LIBSSH2_SFTP_S_IWUSR, \
LIBSSH2_SFTP_S_IROTH
USERNAME = 'user'
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('host', 22))
session = Session()
session.handshake(sock)
session.userauth_password(USERNAME, '')
chan = session.open_session()
chan.execute('ls -ltr')
sftp = session.sftp_init()
mode = LIBSSH2_SFTP_S_IRUSR | \
LIBSSH2_SFTP_S_IWUSR | \
LIBSSH2_SFTP_S_IRGRP | \
LIBSSH2_SFTP_S_IROTH
f_flags = LIBSSH2_FXF_WRITE
remote_fh = sftp.open('input.inp', f_flags, mode)
remote_fh.write('string\n'.encode())
EDIT: just to note that the FIFO pipe is created with mkfifo input.inp
Seems to work for me. LIBSSH2_FXF_APPEND
does exist in sftp module.
from ssh2.sftp import LIBSSH2_FXF_CREAT, LIBSSH2_FXF_WRITE, \
LIBSSH2_SFTP_S_IRUSR, LIBSSH2_SFTP_S_IRGRP, LIBSSH2_SFTP_S_IWUSR, \
LIBSSH2_SFTP_S_IROTH, LIBSSH2_FXF_APPEND
mode = LIBSSH2_SFTP_S_IWUSR
f_flags = LIBSSH2_FXF_CREAT | LIBSSH2_FXF_WRITE | LIBSSH2_FXF_APPEND
remote_fh = sftp.open('input.inp', f_flags, mode)
remote_fh.write('input\n')
(6, 6)
remote_fh.close()
0
Prints input
on fifo stream.
Can also use chan.execute("echo 'input\n' >> input.inp")
as above.
Protocol error is returned by server and indicates improper use of protocol by client code. Looks like create and append flags are needed in this case - the error was 'cannot open file for writing' without them.
Appreciate the code @pkittenis, but even with the copy pasted code I still get the SFTPProtocolError
. It could be that Solaris pipes are different in some way. It's hard to debug since it's such a general error that is raised. I'm not sure what to do next to resolve this. Is there some other info I could provide that would help?
chan.execute()
works of course but I am writing large amounts of data into the pipe and would so really prefer to append directly to it, instead of using echo. My current setup is to write a text file in the same directory via sftp, and then cat file.text > input.inp
. This works but is too clunky for my tastes. Another thing is, I need to wait until the entire text file is written over sftp before I can cat into the pipe. Writing directly to the pipe would mean the commands can start executing as soon as I start writing to the pipe.
What does session.last_error()
return after protocol error? That should give some pointers as to why it is erroring. I do not have a solaris VM at hand but can test on it over weekend probably.
It can only be an issue with libssh2 if there is an issue, however, so most I can do is confirm it does or does not work - ssh2-python binds to libssh2, it does not change how that library behaves at all. Since it works in at least one case, either the SSH server does not implement the protocol correctly or libssh2 behaves differently on that particular server.
Not super useful I am afraid, the output. The Solaris version is SunOS 5.11 11.3 sun4v sparc sun4v
session.last_error()
Out[21]: b''
I'd test with an OpenSSH server. From my regretful experiences with Solaris, its built in SSH server is.. lacking, to put it politely.
Yes, it's a little different to work with :). Sun_SSH_2.4
Could you provide an example on how to open a special file object (FIFO pipe) on the remote machine for writing. I am going through the available examples but none of the provided ones cover this.