2

I have a problem with scala when I want to create a directory remotely via ssh.

ssh commands via scala, such as date or ls, work fine.

However, when I run e.g

"ssh user@Main.local 'mkdir Desktop/test'".!

I get: bash: mkdir Desktop/test: No such file or directory res7: Int = 127

When I copy-paste the command into my shell it executes without any problems.

Does anybody know what is going on??

EDIT:

I found this post : sbt (Scala) via SSH results in command not found, but works if I do it myself

However, the only thing I could take away from it is to use the full path for the directory to be created. However, it still does not work :(

Thanks!

Community
  • 1
  • 1
Marc HPunkt
  • 439
  • 3
  • 14

1 Answers1

3

ssh doesn't require that you pass the entire command line you want to run as a single argument. You're allowed to pass it multiple arguments, one for the command you want to run, and more for any arguments you want to pass that command.

So, this should work just fine, without the single quotes:

"ssh user@Main.local mkdir Desktop/test"

This shows how to get the same error message in an ordinary bash shell, without involving ssh or Scala:

bash-3.2$ ls -d Desktop
Desktop
bash-3.2$ 'mkdir Desktop/test'
bash: mkdir Desktop/test: No such file or directory
bash-3.2$ mkdir Desktop/test
bash-3.2$ 

For your amusement, note also:

bash-3.2$ mkdir 'mkdir Desktop'
bash-3.2$ echo echo foo > 'mkdir Desktop'/test
bash-3.2$ chmod +x 'mkdir Desktop'/test
bash-3.2$ 'mkdir Desktop/test'
foo

UPDATE:

Note that both of these work too:

Process(Seq("ssh", "user@Main.local", "mkdir Desktop/test")).!
Process(Seq("ssh", "user@Main.local", "mkdir", "Desktop/test")).!

Using the form of Process.apply that takes a Seq removes one level of ambiguity about where the boundaries between the arguments lie. But note that once the command reaches the remote host, it will be processed by the remote shell which will make its own decision about where to put the argument breaks. So for example if you wanted to make a directory with a space in the name, this works locally:

Process(Seq("mkdir", "foo bar")).!

but if you try the same thing remotely:

Process(Seq("ssh", "user@Main.local", "mkdir", "foo bar")).!

You'll get two directories named foo and bar, since the remote shell inserts an argument break.

Seth Tisue
  • 29,985
  • 11
  • 82
  • 149
  • Thank you! I only tagged it in scala because the single quotes work in my pure bash script. So I assumed it was a problem with the REPL. Thanks for clearing that up **EDIT**: This can be seen as a scala question since it is logged as a minor bug https://issues.scala-lang.org/browse/SI-7947 – Marc HPunkt Nov 13 '13 at 16:35
  • My original answer falsely claimed that ssh _requires_ command arguments to be separate arguments; it's only _allowed_, not _required_. So you're right that if SI-7947 were addressed, your original command would have worked. I've edited my answer to be worded more narrowly. – Seth Tisue Nov 13 '13 at 18:18