Thanks for the responses, after reading those and doing some additional reading on the tube I understand the difference between callbacks and eventEmitters better.
I'll go away and have a think about how to handle the data event, I'll also try and kick start the node-sftp library that I was using, I think it was fairly close to working properly. So am I right in thinking that I need to parse the stdout data to figure out what command has been run and handle it accordingly? I think that's what the node-sftp library does (example code below). This seems like an alien way of doing things for me but I guess it's similar to handling a request from a browser and determining what script needs to handle the request. /** * Parse the STDOUT of the sftp child process, collect the lines of data for * the active command and detect if the active command has finished executing. * If the active command is done, respective callbacks are called. * * @param {String} data * @type {void} * @private */ function parseReply(data) { //console.log("data: ", data, data.split("\n").length + " parts"); this.emit("data", data); if (!this.activeCmd && !(this.state & Sftp.STATE_CONNECTING)) return; var cbdone, cbprogress; if (data.indexOf("sftp>") > -1 || (this.activeCmd == "bye" && data.indexOf("bye") > -1)) { if (this.state & Sftp.STATE_CONNECTING && this.callbacks["connect"]) { this.callbacks["connect"](); delete this.callbacks["connect"]; } // check if a command has finished executing: else if (cbdone = this.callbacks[this.activeCmd]) { delete this.callbacks[this.activeCmd]; delete this.callbacks[this.activeCmd + "_progress"]; this.activeCmd = null; cbdone((this.activeCmdBuffer + data).split(/[\n\r]+/).filter(function(line) { return line.indexOf("sftp>") === -1; })); this.activeCmdBuffer = ""; } if (!this.activeCmd && this.queue.length && this.state & Sftp.STATE_CONNECTED) this.exec.apply(this, this.queue.shift()); } else if (cbprogress = this.callbacks[this.activeCmd + "_progress"]) { this.activeCmdBuffer += data; cbprogress(data); } } On Monday, 30 July 2012 21:23:35 UTC+1, rhasson wrote: > > "stdin" and "stdout" available on the child process are buffer that > inherit from EventEmitter (well they are streams, unless you change their > behavior when creating the spawned child). As mentioned by Dominic you > need to add event listeners to the data events of the stdout and stderr so > you can see what the FTP process writes. You then need to parse it and > write to the stdin stream while again listening to the stdout and making > sure you received the complete response to the command you sent. > > just be careful not to get into a situation, as you have in your example, > where you register multiple listeners to the same event performing > different tasks. In your example, the outer and inner listeners on stdout > data event will be called when you write "ls" and when you write "rename". > You'll get into an infinite loop very quickly. > > I think you need to create a single data handler that will deal with > processing of all expected output from the FTP process based on all > possible FTP commands you plan to use. Try to make it as generic as > possible so regardless if you did "ls /tmp" or "ls /home" the processing > within the data handler will be the same. You'll need to maintain some > structure outside of the data handler to deal with passing that information > back to the calling function (via callbacks or events). > > If you really want to you can build a TCP server instead that implements > the FTP protocol. Maybe even easier is to copy what other FTP modules did > and just refresh the code and make it your own. > > Roy > > On Monday, July 30, 2012 7:01:43 AM UTC-4, carlton wrote: >> >> Hi there, >> >> I am trying to implent a nodejs script that connects to one of our >> servers using sftp. >> >> So far I can connect using child process and spawning a command such as... >> >> sftp -o Port=22-o PasswordAuthentication=no-o >> UserKnownHostsFile=/home/carlton/.ssh/known_hosts-o >> IdentityFile=private_key-o StrictHostKeyChecking=no-o >> BatchMode=nodeploy@46.x.x.x:/home/carlton/to_process >> >> Now this is the part that has me confused... >> >> I then need to execute commands on the ftp server (e.g. list files, >> rename files) so I listen to the 'data' event.... >> >> sftp.stdout.on('data', function (data) { >> console.log('stdout: ' + data); >> >> sftp.stdin.write("ls -l\r\n"); >> >> sftp.stdout.on('data', function(data){ >> console.log('File list:', data.toString()); >> >> // Parse file names here >> >> sftp.stdin.write("rename >> /home/carlton/FTP_test/to_process/old.php /home/ carlton >> /FTP_test/processed/new.php\n"); >> }); >> }); >> >> Is this the correct way to structure things (i.e. creatiung event >> listener again for the 'data' event within the callback of the previous >> 'data' event listener)? >> I found it hard to find any examples similar to what I need to do which >> made me think I haven't built this as it should have been. >> > -- Job Board: http://jobs.nodejs.org/ Posting guidelines: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines You received this message because you are subscribed to the Google Groups "nodejs" group. To post to this group, send email to nodejs@googlegroups.com To unsubscribe from this group, send email to nodejs+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/nodejs?hl=en?hl=en