Git Product home page Git Product logo

node-ssh's Introduction

Node-SSH - SSH2 with Promises

Node-SSH is an extremely lightweight Promise wrapper for ssh2.

Installation

$ npm install node-ssh # If you're using npm
$ yarn add node-ssh # If you're using Yarn

Example

const fs = require('fs')
const path = require('path')
const {NodeSSH} = require('node-ssh')

const ssh = new NodeSSH()

ssh.connect({
  host: 'localhost',
  username: 'steel',
  privateKeyPath: '/home/steel/.ssh/id_rsa'
})

// or with inline privateKey

ssh.connect({
  host: 'localhost',
  username: 'steel',
  privateKey: Buffer.from('...')
})
.then(function() {
  // Local, Remote
  ssh.putFile('/home/steel/Lab/localPath/fileName', '/home/steel/Lab/remotePath/fileName').then(function() {
    console.log("The File thing is done")
  }, function(error) {
    console.log("Something's wrong")
    console.log(error)
  })
  // Array<Shape('local' => string, 'remote' => string)>
  ssh.putFiles([{ local: '/home/steel/Lab/localPath/fileName', remote: '/home/steel/Lab/remotePath/fileName' }]).then(function() {
    console.log("The File thing is done")
  }, function(error) {
    console.log("Something's wrong")
    console.log(error)
  })
  // Local, Remote
  ssh.getFile('/home/steel/Lab/localPath', '/home/steel/Lab/remotePath').then(function(Contents) {
    console.log("The File's contents were successfully downloaded")
  }, function(error) {
    console.log("Something's wrong")
    console.log(error)
  })
  // Putting entire directories
  const failed = []
  const successful = []
  ssh.putDirectory('/home/steel/Lab', '/home/steel/Lab', {
    recursive: true,
    concurrency: 10,
    // ^ WARNING: Not all servers support high concurrency
    // try a bunch of values and see what works on your server
    validate: function(itemPath) {
      const baseName = path.basename(itemPath)
      return baseName.substr(0, 1) !== '.' && // do not allow dot files
             baseName !== 'node_modules' // do not allow node_modules
    },
    tick: function(localPath, remotePath, error) {
      if (error) {
        failed.push(localPath)
      } else {
        successful.push(localPath)
      }
    }
  }).then(function(status) {
    console.log('the directory transfer was', status ? 'successful' : 'unsuccessful')
    console.log('failed transfers', failed.join(', '))
    console.log('successful transfers', successful.join(', '))
  })
  // Command
  ssh.execCommand('hh_client --json', { cwd:'/var/www' }).then(function(result) {
    console.log('STDOUT: ' + result.stdout)
    console.log('STDERR: ' + result.stderr)
  })
  // Command with escaped params
  ssh.exec('hh_client', ['--json'], { cwd: '/var/www', stream: 'stdout', options: { pty: true } }).then(function(result) {
    console.log('STDOUT: ' + result)
  })
  // With streaming stdout/stderr callbacks
  ssh.exec('hh_client', ['--json'], {
    cwd: '/var/www',
    onStdout(chunk) {
      console.log('stdoutChunk', chunk.toString('utf8'))
    },
    onStderr(chunk) {
      console.log('stderrChunk', chunk.toString('utf8'))
    },
  })
})

API

// API reference in Typescript typing format:
import SSH2, {
  AcceptConnection,
  Channel,
  ClientChannel,
  ConnectConfig,
  ExecOptions,
  Prompt,
  PseudoTtyOptions,
  RejectConnection,
  SFTPWrapper,
  ShellOptions,
  TcpConnectionDetails,
  TransferOptions,
  UNIXConnectionDetails,
} from 'ssh2'
import stream from 'stream'

// ^ You do NOT need to import these package, these are here for reference of where the
// types are coming from.

export type Config = ConnectConfig & {
  password?: string
  privateKey?: string
  privateKeyPath?: string
  tryKeyboard?: boolean
  onKeyboardInteractive?: (
    name: string,
    instructions: string,
    lang: string,
    prompts: Prompt[],
    finish: (responses: string[]) => void,
  ) => void
}
export interface SSHExecCommandOptions {
  cwd?: string
  stdin?: string | stream.Readable
  execOptions?: ExecOptions
  encoding?: BufferEncoding
  noTrim?: boolean
  onChannel?: (clientChannel: ClientChannel) => void
  onStdout?: (chunk: Buffer) => void
  onStderr?: (chunk: Buffer) => void
}
export interface SSHExecCommandResponse {
  stdout: string
  stderr: string
  code: number | null
  signal: string | null
}
export interface SSHExecOptions extends SSHExecCommandOptions {
  stream?: 'stdout' | 'stderr' | 'both'
}
export interface SSHPutFilesOptions {
  sftp?: SFTPWrapper | null
  concurrency?: number
  transferOptions?: TransferOptions
}
export interface SSHGetPutDirectoryOptions extends SSHPutFilesOptions {
  tick?: (localFile: string, remoteFile: string, error: Error | null) => void
  validate?: (path: string) => boolean
  recursive?: boolean
}
export type SSHMkdirMethod = 'sftp' | 'exec'
export type SSHForwardInListener = (
  details: TcpConnectionDetails,
  accept: AcceptConnection<ClientChannel>,
  reject: RejectConnection,
) => void
export interface SSHForwardInDetails {
  dispose(): Promise<void>
  port: number
}
export type SSHForwardInStreamLocalListener = (
  info: UNIXConnectionDetails,
  accept: AcceptConnection,
  reject: RejectConnection,
) => void
export interface SSHForwardInStreamLocalDetails {
  dispose(): Promise<void>
}
export class SSHError extends Error {
  code: string | null
  constructor(message: string, code?: string | null)
}

export class NodeSSH {
  connection: SSH2.Client | null

  connect(config: Config): Promise<this>
  isConnected(): boolean
  requestShell(options?: PseudoTtyOptions | ShellOptions | false): Promise<ClientChannel>
  withShell(
    callback: (channel: ClientChannel) => Promise<void>,
    options?: PseudoTtyOptions | ShellOptions | false,
  ): Promise<void>
  requestSFTP(): Promise<SFTPWrapper>
  withSFTP(callback: (sftp: SFTPWrapper) => Promise<void>): Promise<void>
  execCommand(givenCommand: string, options?: SSHExecCommandOptions): Promise<SSHExecCommandResponse>
  exec(
    command: string,
    parameters: string[],
    options?: SSHExecOptions & {
      stream?: 'stdout' | 'stderr'
    },
  ): Promise<string>
  exec(
    command: string,
    parameters: string[],
    options?: SSHExecOptions & {
      stream: 'both'
    },
  ): Promise<SSHExecCommandResponse>
  mkdir(path: string, method?: SSHMkdirMethod, givenSftp?: SFTPWrapper | null): Promise<void>
  getFile(
    localFile: string,
    remoteFile: string,
    givenSftp?: SFTPWrapper | null,
    transferOptions?: TransferOptions | null,
  ): Promise<void>
  putFile(
    localFile: string,
    remoteFile: string,
    givenSftp?: SFTPWrapper | null,
    transferOptions?: TransferOptions | null,
  ): Promise<void>
  putFiles(
    files: {
      local: string
      remote: string
    }[],
    { concurrency, sftp: givenSftp, transferOptions }?: SSHPutFilesOptions,
  ): Promise<void>
  putDirectory(
    localDirectory: string,
    remoteDirectory: string,
    { concurrency, sftp: givenSftp, transferOptions, recursive, tick, validate }?: SSHGetPutDirectoryOptions,
  ): Promise<boolean>
  getDirectory(
    localDirectory: string,
    remoteDirectory: string,
    { concurrency, sftp: givenSftp, transferOptions, recursive, tick, validate }?: SSHGetPutDirectoryOptions,
  ): Promise<boolean>
  forwardIn(remoteAddr: string, remotePort: number, onConnection?: SSHForwardInListener): Promise<SSHForwardInDetails>
  forwardOut(srcIP: string, srcPort: number, dstIP: string, dstPort: number): Promise<Channel>
  forwardInStreamLocal(
    socketPath: string,
    onConnection?: SSHForwardInStreamLocalListener,
  ): Promise<SSHForwardInStreamLocalDetails>
  forwardOutStreamLocal(socketPath: string): Promise<Channel>
  dispose(): void
}

Typescript support

node-ssh requires extra dependencies while working under Typescript. Please install them as shown below

yarn add --dev @types/ssh2
# OR
npm install --save-dev @types/ssh2

If you're still running into issues, try adding these to your tsconfig.json

{
  "compilerOptions": {
    "moduleResolution": "node",
    "allowSyntheticDefaultImports": true
  }
}

Keyboard-interactive user authentication

In some cases you have to enable keyboard-interactive user authentication. Otherwise you will get an All configured authentication methods failed error.

Example:

const password = 'test'

ssh.connect({
  host: 'localhost',
  username: 'steel',
  port: 22,
  password,
  tryKeyboard: true,
})

// Or if you want to add some custom keyboard-interactive logic:

ssh.connect({
  host: 'localhost',
  username: 'steel',
  port: 22,
  tryKeyboard: true,
  onKeyboardInteractive(name, instructions, instructionsLang, prompts, finish) {
    if (prompts.length > 0 && prompts[0].prompt.toLowerCase().includes('password')) {
      finish([password])
    }
  }
})

For further information see: mscdex/ssh2#604

License

This project is licensed under the terms of MIT license. See the LICENSE file for more info.

node-ssh's People

Contributors

acionyx avatar dadamssg avatar davefinster avatar dependabot-preview[bot] avatar dependabot-support avatar dependabot[bot] avatar dimfeld avatar dominiklessel avatar greenkeeper[bot] avatar greenkeeperio-bot avatar jackpap avatar jamesrom avatar jldowns avatar kawasako avatar kimbob13 avatar kirrg001 avatar lanxenet avatar maquak avatar mat-sz avatar mateussilva92 avatar neatdecisions avatar nicram97 avatar sikarii avatar smali-kazmi avatar steelbrain avatar wmertens avatar yuanfang-dev avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

node-ssh's Issues

Error when using put and create directories

NodeSSH = require('node-ssh');

var ssh = new NodeSSH();

ssh.connect({
    host: 'host',
    username: 'user',
    password: 'pass'
}).then(function() {
    return ssh.put('dist/index.html', 'foo/index.html').then(function() {
        console.log('done');
    });
}).catch(function(err) {
    console.error(err);
});

Note that I'm uploading to an non-existent directory. I remember in v1.0.0 this directory got created automatically. But when I run the above script I get Fatal error: Cannot read property 'mkdir' of undefined again.

Get full path in shell

Hello, have a problem, how I can get the full path in shell?

ssh.connect(sshConfig).then(() => {
  ssh.requestShell().then((stream) => {
    const stdin = process.openStdin();

    stdin.addListener('data', data => {
      //need to know full path here

      // Trim input to prevent the endings of lines in Windows ('\r\n\')
        stream.write(data.toString().trim() + '\n');
    });

    stream.on('data', data => {
      process.stdout.write(data);
    }).stderr.on('data', data => {
      process.stdout.write(data);
    });
  });
});

Support Shell

Currently we only support exec, we even have to append the cwd to the command it doesn't give us a decent way to write stdin either.
So if we support ssh2's shell. We'll have cwd support as well as stdin write support.

Streams not closing properly

When chaining many .then() blocks, I get

Error: (SSH) Channel open failure: open failed

due to hitting the max number of connections to my remote server. I think this is the same issue as mscdex/ssh2#219 . I added some .close() calls before the Promise resolutions and it solved my problem.

I'll submit a pull request with what worked for me, although I don't have any test scripts to run it against.

putDirectory fails with no such file recursively

When I try to use the function ssh.putDirectory() and transfer an entire directory and its files recursively, it transfers all the directories correctly but fails to transfer any files. I receive an error

{ [Error: No such file] code: 2, lang: '' }

If I set recursive to false then it transfers the one file in the base directory just fine. Please advise. I am using the example provided.

Thanks.

Promise put doesn't get fulfilled if new directories have to be created

Hey @steelbrain, awesome repo! I have spottet a annoying bug โ€“ or maybe I'm doing it wrong? Try this code and make sure that the remote/path/to/file.file doesn't exist, so that node-ssh has to create those dirs. When I run the code then, my script stops and Node is stuck. But weirdly the remote directories get created and the file gets uploaded. So I have to force stop the script and restart it. After the restart it proceeds to the other files as expected until it has to create directories again. Do you have an idea for that problem?

This looks a little bit similar to #4.

var NodeSSH = require('node-ssh'),
    config  = require('./deploy_info.json');

var ssh = new NodeSSH({
  host:     config.host,
  username: config.username,
  password: config.password
});

ssh.connect().then(function() {
  ssh.put('local/path/to/file.file', 'remote/path/to/file.file').then(function() {
    ssh.end();
  }, function(err) {
    console.error(err);
  });
});

option to kill exec or send asynchron stdin

Is it possible to kill a exec command or send asynchron stdin without closing the ssh connection?
My workaround is to let the executed program print its pid. So I can later exec(kill, pid). Is there better way?

Streaming stdout/stderr for long-running commands

The current exec() call only calls a callback function when the command is done, providing the entire console output as a buffer.

It would be nice to have an alternative call where one can receive output as it is produced, while the command takes long to finish (specially if it is writing its progress to stdout!).

Currently I am using this on a project, and had to switch to ssh2 for this part -- but I like the promises approach more, so would like to keep using node-ssh.

Encrypted private keys?

I'm getting an error UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): Error: Encrypted private key detected, but no passphrase given but not sure if I've missed a way to prompt for or define the passphrase?

Concurrent requests on same connection?

I'm running a for loop which invokes 15+ ssh2 connections.

// more code...
const ssh = new SSH({});
await ssh.connect({
        host: host,
        username: user,
        port: port,
        privateKey: key,
    });

I run this 15 times in a for loops quickly, creating concurrent ssh requests (or at least trying to create concurrent requests).

await ssh.execCommand(cmd);

I get the following error on all of the connections except the first one:

{ Error: (SSH) Channel open failure: open failed
    at SSH2Stream.onFailure (/builds/b/e/node_modules/node-ssh/node_modules/ssh2/lib/client.js:1068:13)
    at Object.onceWrapper (events.js:316:30)
    at emitOne (events.js:115:13)
    at SSH2Stream.emit (events.js:210:7)
    at parsePacket (/builds/b/e/node_modules/ssh2-streams/lib/ssh.js:3423:10)
    at SSH2Stream._transform (/builds/b/e/node_modules/ssh2-streams/lib/ssh.js:551:13)
    at SSH2Stream.Transform._read (_stream_transform.js:190:10)
    at SSH2Stream._read (/builds/b/e/node_modules/ssh2-streams/lib/ssh.js:212:15)
    at SSH2Stream.Transform._write (_stream_transform.js:178:12)
    at doWrite (_stream_writable.js:371:12)
    at writeOrBuffer (_stream_writable.js:357:5)
    at SSH2Stream.Writable.write (_stream_writable.js:274:11)
    at Socket.ondata (_stream_readable.js:626:20)
    at emitOne (events.js:115:13)
    at Socket.emit (events.js:210:7)
    at addChunk (_stream_readable.js:250:12) reason: 'CONNECT_FAILED', lang: '' }

This leads me to understand that this package does not support concurrent requests on the same connection? I'm guessing I must open a new connection per request?

Handle retries properly

There are times when we have to wait for the continue event before sending more traffic, not urgent but good to have

Executing commands like npm, node, and gulp

I am trying to script a build process with several different commands.
I am using git commands successfully like this:

return ssh.execCommand('git fetch --all', standardExecCmdOptions);

But I am unable to use any node based commands (node, npm, gulp, etc...) such as:

return ssh.execCommand('npm install', standardExecCmdOptions)

or

return ssh.execCommand("gulp build:test", standardExecCmdOptions)

Node is definitely installed. If I SSH directly into the machine and type the commands in manually, it works as expected (gulp is found, npm is found, etc...)

The error messages I get are simply:

bash: gulp: command not found
bash: npm: command not found

Like I said, the git commands are working, the node commands are not. Any clue what I could be doing wrong?

Thanks!

Example on how to end a connection

Copy/pasting the example in the readme.md, the connection is not closed at the end of the process, could you please give an example?
I saw this thread about the end() method, but it does not work to me.
It gives me TypeError: ssh.end is not a function.
Thank you.

Can you use exec or execCommand to run a bash script?

Im trying to upload a bash file to the server and then would like to execute it. would it be possible to do so and stream the output back?

I been messing around with the lib and tried both exec and execCommand

ssh.exec('bash provision.sh', {cwd: '/var/deployer', stream: 'stdout'})
                        .then(result => {
                            ErrorHandler.instance.info(result);
                            ssh.dispose();
                        })
                        .catch(error => {
                            ErrorHandler.instance.error('Somthing went wrong with provisioning \n' + error)
                        })

Error i get

[Wed Feb 01 2017 18:17:52 GMT+0200 (FLE Standard Time)] ERROR Somthing went wrong with provisioning 
TypeError: a.forEach is not a function
                    ssh.execCommand('bash provision.sh', {cwd: '/var/deployer', stream: 'stdout'})
                        .then(result => {
                            ErrorHandler.instance.info(result);
                            ssh.dispose();
                        })
                        .catch(error => {
                            ErrorHandler.instance.error('Somthing went wrong with provisioning \n' + error)
                        })
                })

Error

signal: undefined,
  stdout: 'Reading package lists...\nBuilding dependency tree...\nReading state information...\ndeb http://packages.blackfire.io/debian any main\nExecuting: /tmp/tmp.YR346mP862/gpg.1.sh --recv-keys\n--keyserver\nhkp://keyserver.ubuntu.com:80\n0xcbcb082a1bb943db\r\nReading package lists...\nBuilding dependency tree...\

Missing end() wrapper

From what i see it's actually impossible to close a connection because you can't access the end() method of the underlying ssh2 connection object.

Implement sftp mkdir()

Just like the title says. It'll allow using this package on sftp-only servers where no exec is allowed.

Max number of commands ?

Heyho !

I'm running into an issue with the module.
I'm trying to run an exec command in a callback of another function. I'm checking if the connection is done beforehand then run the command.
In total, i'm doing two commands per data, which is 2 * 25 commands, first being an exec "find" and second a get file.
However, it seems that what ever I try, the exec command will always stop after 20 calls.
Any idea where to look ?
Cheers,

EDIT:

I tried with the following code, it stops after 20 commands:

var node_ssh = require('node-ssh');
var connectAttr = require('./connectionAttr');

var ssh = new node_ssh(connectAttr);

ssh.connect().then(function () {
    for (var i = 1; i < 30; i++) {
        ssh.exec('echo ' + i).then(function (std) {
            console.log(std.stdout);
        });
    }
});

Uncaught TypeError: undefined is not a function

From @raeesiqbal on April 12, 2015 16:45

Atom Version: 0.190.0
System: Microsoft Windows 10 Pro Technical Preview
Thrown From: autocomplete-hack package, v0.1.1

Stack Trace

Uncaught TypeError: undefined is not a function

At C:\Users\Raees\.atom\packages\autocomplete-hack\node_modules\node-ssh\Dist\SSH.js:82

TypeError: undefined is not a function
    at Readable.<anonymous> (C:\Users\Raees\.atom\packages\autocomplete-hack\node_modules\node-ssh\Dist\SSH.js:82:38)
    at emitOne (events.js:77:13)
    at Readable.emit (events.js:166:7)
    at Readable.read (_stream_readable.js:356:10)
    at flow (_stream_readable.js:734:26)
    at resume_ (_stream_readable.js:714:3)
    at _stream_readable.js:701:7
    at process._tickCallback (node.js:357:13)

Commands

  6x -6:31.7 core:save (atom-text-editor.editor)
     -1:58.0 settings-view:check-for-package-updates (atom-workspace.workspace.scrollbars-visible-always.theme-one-dark-syntax.theme-one-dark-ui)
     -1:43.8 core:move-right (div.settings-view.pane-item)
     -0:03.5 core:undo (atom-text-editor.editor.is-focused)
     -0:01.0 editor:select-to-beginning-of-word (atom-text-editor.editor.is-focused)
     -0:00.5 core:backspace (atom-text-editor.editor.is-focused)

Config

{
  "core": {}
}

Installed Packages

# User
Atom-Hack, v3.5.4
autocomplete-hack, v0.1.1
autocomplete-plus, v2.9.0
language-hack, v0.1.1
open-last-project, v0.4.1

# Dev
No dev packages

Copied from original issue: steelbrain/autocomplete-hack#3

Calling Script via ssh.exec does not seem to produce expected result

Hi,

I am able to access my virtual machine via node-ssh. Inside my virtual machine, I have a /home/dake/Downloads/install.sh. Inside the script contains nothing but many echo statement.

When i run the below code, my console did print out connect!
Although ssh.exec get triggered, but the function(result) inside the ssh.exec does not print out the 2 console logging. This shows that the this function(result) does not get triggered at all.
May i know what is the issue of my code below?

let NODE_SSH = require('node-ssh')
    let ssh = new NODE_SSH()

    ssh.connect({
        host:'192.168.123.111',
        username:'xxxx',
        password:'yyyy'

    }).then(
        function(){
            console.log("connect!")
   
            ssh.exec('/home/dake/Downloads/install.sh').then(function(result) {
                  console.log("inside")
                  console.log(result.stdout)

            })
    )

How to switch to root user

When I do sudo -i and then trying to execute commands, it's not working. It just stops executing then after

PATH variable lost when issuing new command

I had some troubles getting a correct path setup using node-ssh.
This is an example of something i tried:

ssh.execCommand('export PATH="$PATH:/something/to/be/added/bin"', [], {})
    .then(function(result) {
      ssh.execCommand( "echo $PATH" , [], { } )
        .then(function(out){
          console.log(out.stdout);
          //will output path does not contain /something/to/be/added/bin
          ssh.dispose();
        });
    });

I also tried updating my ~/.bash_profile and ~/.bashrc files to set the path correctly, and even explicitly sourced these files via the .execCommand("source ~/.bash_profile") but to no avail. Every subsequent lost the path variables set in the original one.

Not sure if this is an issue or wanted behaviour (to not pollute env), but how should you make sure node-ssh has the correct environment?

ssh.dispose should be a promise?

Trying to build a script in top of this cool module, but was surprise why .dispose() was not wrap into a promise?

just to keep it align with the other api methods, what you think?

exec doesn't return result ?

The node code below return in the browser:
Hello world
Start SSH connection.SSH connection OK.disconnect.

It means that the exec function was unable to send back the stdout result !
This behaviour is strange, because, I get no error from the exec() function itself, while a catch has been set.

'use strict';
const express = require('express');
// Constants
const PORT = 8888;
var node_ssh, ssh;
// App
const app = express();
app.get('/', function (req, res) {
  res.write('Hello world\n');
node_ssh = require('node-ssh');
ssh = new node_ssh();
res.write('Start SSH connection.');
ssh.connect({
  host: 'platform.eexample.com',
  username: 'user',
  password: 'password'
})
  .then(function() {
  // Command
  res.write('SSH connection OK.');
  ssh.exec('/bin/ls', ['-al'], {cwd:'.', stream: 'both'}).then(function(result) {
    res.write('STDOUT: ' + result.stdout);
    res.write('STDERR: ' + result.stderr);
  }).catch(function(err) {
    res.write("error!", err.stack);
    res.end();
  });
  res.write('disconnect.');
  ssh.end();
  res.end();
  })
  .catch(function(err) {
    res.write("error!", err.stack);
    res.end();
  });
});
app.listen(PORT);
console.log('Running on http://localhost:' + PORT);

not able to make a put of a directory?

at first thanks for the work.
I want to use this library to move something downloaded in a raspberry to a server and it can be files or directories, but it fail when i'm trying to make a put of a directory, the error is:
"{ [Error: EISDIR: illegal operation on a directory, read] errno: -21, code: 'EISDIR', syscall: 'read' }"
it's not going to be able to make a scp of a directory or is a fail?

getFile documentation is confused

Hey! :)

I would like to ask what returns the getFile method. I mean, I'm sure that returns a promise. But in some parts of the documentation says that returns a void promise:
getFile(localFile: string, remoteFile: string, sftp: ?Object = null, opts: ?Object = null): Promise<void>
in other part say that return the content:
ssh.getFile('/home/steel/Lab/localPath', '/home/steel/Lab/remotePath').then(function(Contents) {
and in your tests you are checking if the file exists:
await client.getFile(targetFile, sourceFile)
expect(await exists(targetFile)).toBe(true)
Maybe, the promise is solved with the content and also the file is created, but is not clear for me and i want to be sure of that. Let me know if I wasn't clear :)

Thanks!

Execute command with input

When I access my device through SSH I need to enable it. Enabling it takes 2 steps:

  • executing "en"
  • the command line requests an input
  • the input should be "lab"

This is what I tried to do:

ssh.connect({
        host: 'my-host',
        username: 'test',
        password: 'test123'
    }).then(function(result1) {
        console.log('Connected!');
        console.log('Executing "en"');
        console.log('STDOUT: ' + result1.stdout)
        console.log('STDERR: ' + result1.stderr)
        ssh.exec('en').then(function(result2) {
            console.log('Executing "lab"');
            console.log('STDOUT: ' + result2.stdout);
            console.log('STDERR: ' + result2.stderr);
            ssh.execCommand('lab').then((function(result3) {
                    console.log('Lab Executed!');
                    console.log('STDOUT: ' + result3.stdout)
                    console.log('STDERR: ' + result3.stderr)
                }
            ));
        }, function (error) {
            res.send('Error');
        })
    })

in Putty the command are working

In my NodeJS app I get the following console output:

Example app listening on port 3000!
Connected!
Executing "en"
STDOUT: undefined
STDERR: undefined
Executing "lab"
STDOUT: undefined
STDERR: undefined
(node:18252) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): Error: write ECONNABORTED

Any idea what I'm missing?

Get directory listing

Hello,
Thank you for your work :)
It's possible to get the directory listing in the JSON format please ?

Thx

ssh.get() parameters are reversed

Hey steelbrain,

i noticed that the documentation of the get()-function is reversed.

the FIRST parameter is the local folder and the SECOND is the remote folder

get(remoteFile, localFile, SFTP) {

as you see here

SFTP.fastGet(localFile, remoteFile, function(err){

Inconsistence in README.md?

I searched for Remote -> Local example... and found:

On npm project page I see:

// Local, Remote 
ssh.getFile('/home/steel/Lab/RemoteSource', '/home/steel/Lab/LocalTarget')

but on github:

// Local, Remote
ssh.getFile('/home/steel/Lab/localPath', '/home/steel/Lab/remotePath')

Error when using put

NodeSSH = require('node-ssh');

var ssh = new NodeSSH();

ssh.connect({
    host: 'host',
    username: 'user',
    password: 'pass'
}).then(function() {
    return ssh.put('dist/index.html', 'index.html').then(function() {
        console.log('done');
    });
}).catch(function(err) {
    console.error(err);
});

Getting this Error: [TypeError: Cannot read property 'fastPut' of undefined]. Local file exists and should be uploaded.

All configured authentication methods failed

Env:Windows 10,Node 8.9.1,Npm 5.2.0.
(node:12768) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: All configured authentication methods failed
(node:12768) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

TypeError: a.forEach is not a function

Hello,

I'm trying to execute some executable on remote machine and leave the executable to run in the background.
When I'm executing it using exec I got this error:
Error: TypeError: a.forEach is not a function

This is what I tried:

let sshClient = new ssh();
    sshClient.connect({
        host: '34.239.19.87',
        username: 'ubuntu',
        privateKey: '/home/user/key.pem'}).
    then(function () {
        let command = './cct_proxy -i ' + partyId + ' -c ' +
        numberOfParties + ' -f parties.conf -l 700 -p ' + portNumber + ' &';
        sshClient.exec(command, {cwd:'/home/ubuntu/ACP/cct_proxy',
            options: { pty: true } }).
        then(function (result) {
            console.log('STDOUT: ' + result.stdout);
            console.log('STDERR: ' + result.stderr);
        }).catch(function (error) {
            console.log('Error: ' + error);
        });
    }).
    catch(function (error) {
      console.log('Error: ' + error);
    });

Fails with no error on windows 7 system

Trying to figure out how to diagnose this further. I have a connection as shown below. On OSX, Windows 7 64 bit and a Windows 10 system this connection works with no problems. However on 1 Windows 7 64 bit system the application never even displays the first log.info command (FIRST SSH RESULT ---). My understanding was that even if there was an error connecting I would at least get this far. Is there some other error handeling I'm missing? Is there any other items that need to be installed on a windows 7 system before this can work properly? If I could at least find a way to see an error that would be very helpful.

let ssh = new node_ssh();
  ssh.connect({
    host: deviceIP,
    username: 'myuser',
    password: 'mypass',
    agent: 'pageant',
  }).then(function () {
    ssh.execCommand(command, {cwd: '/var/www'}).then(function (result) {
      log.info('FIRST SSH RESULT ---');
      log.info('STDOUT: ' + result.stdout);
      log.info('STDERR: ' + result.stderr);
    });
  });

Edit by @steelbrain: Fix formatting

Promise Rejected - All configured authentication methods failed

The whole task is to stop an aws instance from backend and then restarting the same, once the instance is running, I need to run few commands after connecting through ssh.
I am getting the instance status as "Running" as well.
I tried to access the same instance from Putty, I got error message saying "Disconnected: No supported authentication methods available(server sent: publickey)".

This is my code where I am trying to connect to an instance:-

console.log("instance status: ", status)
ssh.connect({
host: publicIp,
username: '*',
readyTimeout: 99999,
privateKey: '.pem'
}).then(function(result) {
console.log("result: ", result);
});

Error:
instance status: running
(node:37) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: All configured authentication methods failed
(node:37) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

note: For the first time, this was working.

Can anyone tell me what am I doing wrong here?

putDirectory function fails to create remote folders if empty

Hello,

I'm using this library to copy directories from a local environment (using angular2 + Electron) to a remote server. It works really well when I use the "putDirectory" function if I have a directory with folders and files in them, but fails to copy empty folders, no matter where it's stored. If a folder contains an empty folder, this parent folder is not created either. Why is this happening? Thank you.

Cheers.

Support for pty?

I have a couple different bash script I'm running from a lambda function for an alexa skill. One of which requires pty. I didnt see any option to enable it. Is this something that can be added easily? Thanks this lib was majorly helpful

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.