<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<style type="text/css" style="display:none;"><!-- P {margin-top:0;margin-bottom:0;} --></style>
</head>
<body dir="ltr">
<div id="divtagdefaultwrapper" style="font-size: 12pt; color: rgb(0, 0, 0); font-family: Calibri, Helvetica, sans-serif, EmojiFont, "Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Segoe UI Symbol", "Android Emoji", EmojiSymbols;" dir="ltr">
<p style="margin-top:0;margin-bottom:0">Hi Hans!<br>
<br>
I've started to look into this. I did a trace using redbug and as far as I can tell I don't end up in the section with the comment <span>"The F communicates via standard io:write/read." but rather end up in the section with the comment "<span>%% Exec called
 and the shell is the default shell (= Erlang shell).". </span></span></p>
<p style="margin-top:0;margin-bottom:0"><span><span>This was assuming that the I/O not coming back for the exec case is a bug. </span></span></p>
<p style="margin-top:0;margin-bottom:0"><br>
</p>
<p style="margin-top:0;margin-bottom:0"><b>My redbug output:</b></p>
<p style="margin-top:0;margin-bottom:0"><span></span></p>
<div>% 14:10:33 <22297.5495.0>({ssh_client_channel,init,1})</div>
<div>% ssh_cli:handle_ssh_msg({ssh_cm,<22297.4959.0>,</div>
<div>        {exec,1,false, <span style="font-size: 12pt;">"</span><span style="font-size: 14.6667px;">sshtest</span><span style="font-size: 12pt;">:</span><span style="font-size: 14.6667px;">sshIO()</span><span style="font-size: 12pt;">."}}, </span></div>
<div>        {state,undefined,undefined,undefined,undefined,undefined, <span style="font-size: 12pt;">{shell,start,[]}, </span><span style="font-size: 12pt;">undefined})</span></div>
<div><span style="font-size: 12pt;"><br>
</span></div>
<div><span style="font-size: 12pt;">Which means, as far as I can tell, that no I/O is given back (there is no I/O handling from what I can see in the function ssh_clki:exec_in_erlang_default_shell/1.</span></div>
<div><span style="font-size: 12pt;"><br>
</span></div>
<div><span style="font-size: 12pt;">Thanks for any help I can get <span>😊</span></span></div>
<div>Best regards,</div>
<div>Tommy Mattsson</div>
<br>
<p></p>
<br>
<br>
<div style="color: rgb(0, 0, 0);">
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" style="font-size:11pt" color="#000000"><b>From:</b> Hans Nilsson R <hans.r.nilsson@ericsson.com><br>
<b>Sent:</b> Tuesday, November 6, 2018 10:43 AM<br>
<b>To:</b> Mattsson, Tommy; Per Hedeland<br>
<b>Cc:</b> erlang-questions@erlang.org<br>
<b>Subject:</b> Re: [erlang-questions] Erlang ssh shell question</font>
<div> </div>
</div>
<div class="BodyFragment"><font size="2"><span style="font-size:11pt;">
<div class="PlainText">Hi Tommy and Hi Per too :)<br>
<br>
Sorry for my sloppy reading of your first mail, but now I think I understand you.<br>
<br>
To start an Erlang server executing "shell" or "exec" commands you just start a normal server (= daemon):<br>
Erlang/OTP 21 [erts-10.1.1] [source-3094642] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe]<br>
<br>
2> ssh:daemon(1236, [{system_dir,"XXX"}]).  % (will get ~/.ssh as user_dir where ~ is the home of the user that started erl)<br>
<br>
and elsewhere in a bash:<br>
<br>
~$ ssh -p 1236 localhost<br>
Eshell V10.1.1  (abort with ^G)<br>
1> io:write(hej).<br>
hejok<br>
2> exit().<br>
~$<br>
<br>
or, for "exec":<br>
<br>
~$ ssh -p 1236 localhost 1+2.<br>
3<br>
~$<br>
<br>
etc.<br>
<br>
<br>
Now as I understand, you want to do I/O in the command and expect:<br>
<br>
~$ ssh -p 1236 localhost 'io:write(hejsan).'<br>
hejsan<br>
~$<br>
<br>
but you get:<br>
<br>
~$ ssh -p 1236 localhost 'io:write(hejsan).'<br>
ok<br>
~$<br>
<br>
and hejsan is written in the shell of the server started above.<br>
<br>
<br>
You could start your own exec command interpreter with the option 'exec' to the server:<br>
<br>
(See <a href="http://erlang.org/doc/man/ssh.html#type-exec_daemon_option" id="LPlnk35831" class="OWAAutoLink" previewremoved="true">
http://erlang.org/doc/man/ssh.html#type-exec_daemon_option</a><br>
 but NOTE: ERROR in that one.....<br>
  should be<br>
      {exec, {direct, 'exec_fun/1'() | 'exec_fun/2'() | 'exec_fun/3'()} }<br>
 )<br>
<br>
Example:<br>
9> ssh:daemon(1237, [{system_dir,"XXX"}, {exec, {direct,  fun(Cmd) -> {ok, {got,Cmd}} end  }}]).<br>
<br>
and from a separate bash shell:<br>
<br>
~$ ssh -p 1237 localhost 'io:write(hejsan).'<br>
{got,"io:write(hejsan)."}~$<br>
<br>
This gives a clue on what to do:<br>
"Just" write something executing the command grabbing the output and return it in that {direct,fun(Cmd)...} as a string...<br>
<br>
Now I think that not returning I/O from an exec command is a bug. However I can't look into that now and probably not on this side of christmas.<br>
IF you should like to dig into this, the central function is ssh_cli:handle_ssh_msg/2 line 114.  The clause with the head:<br>
    handle_ssh_msg({ssh_cm, ConnectionHandler,  {exec, ChannelId, WantReply, Cmd}}, S0) -><br>
<br>
There are comments in that code which could give you some clues.  There is also a comment with "The F communicates via standard io:write/read.".<br>
That makes me belive that I accidently changed some functionality when I restructured this part. I will look into that too, but not now.<br>
<br>
I hope you got some ideas, and just ask if you wonder about something. And Pull Requests are welcome!<br>
<br>
/Hans<br>
<br>
On 11/6/18 9:24 AM, Mattsson, Tommy wrote:<br>
> Hi Per and Hans,<br>
> <br>
> Thank you both for your replies! ðŸ˜Š<br>
> Per is correct, I want to execute "ssh <host> <cmd>" from a regular shell (bash, etc.) and have it connect to the Erlang SSH shell that I started on <host> and give me output like there was "echo test1", "echo test2" in a bash script.<br>
> <br>
> <br>
> I will look into if I can make use of the exec functionality for the Erlang SSH server. I looked at it earlier but it seemed to me that its intended use was for an Erlang SSH client connecting to an Erlang SSH server so I dismissed that as an option.<br>
> <br>
> If all else fails I could look into the ssh_cli option and see if I can have an Erlang SSH shell handle I/O differently than the default.<br>
> <br>
> <br>
> Best regards,<br>
> <br>
> Tommy<br>
> <br>
> ________________________________<br>
> From: Per Hedeland <per@hedeland.org><br>
> Sent: Friday, November 2, 2018 11:30:33 AM<br>
> To: Hans Nilsson R; Mattsson, Tommy<br>
> Cc: erlang-questions@erlang.org<br>
> Subject: Re: [erlang-questions] Erlang ssh shell question<br>
> <br>
> Hi Tommy! (and Hans:-)<br>
> <br>
> Hans, I *think* you are misunderstanding Tommy's question. More<br>
> speculation below, since I haven't actually verified how ssh(3)<br>
> works... When using e.g. the OpenSSH client,<br>
> <br>
> $ ssh <host><br>
> <br>
> makes a "shell" request per<br>
> <a href="https://tools.ietf.org/html/rfc4254#section-6.5" id="LPlnk74333" class="OWAAutoLink" previewremoved="true">
https://tools.ietf.org/html/rfc4254#section-6.5</a> , while<br>
> <br>
> $ ssh <host> <cmd><br>
> <br>
> makes an "exec" request. I think Tommy is happy with how "shell" works,<br>
> but you seem to be changing it to a pretty boring implementation.:-) And<br>
> I think Tommy's question is about "exec" not associating 'standard_io'<br>
> with the SSH channel - thus if you use "exec" to call a function that<br>
> prints something, the output is lost.<br>
> <br>
> I'm not sure there is anything "wrong" with that though - for an SSH<br>
> server running "directly" on *nix, it is obvious that "exec" should<br>
> associate stdio with the SSH channel, since <cmd> is *nix shell command,<br>
> and it's pretty fundamental that you want any output (and exit code)<br>
> that it produces. But for the Erlang/OTP SSH server, <cmd> is<br>
> (apparently) an Erlang function call, and sending only what the call<br>
> returns (in text form) back through the channel is not unreasonable per<br>
> se.<br>
> <br>
> But maybe there could be an option to ssh:daemon() to make it do the<br>
> same thing with 'standard_io' for "exec" as it does for "shell" - I<br>
> can't see one in the man page. And I can't think of a way that the<br>
> called function could set it up. But I assume that it's possible to<br>
> do-it-all yourself via the 'ssh_cli' option.<br>
> <br>
> --Per<br>
> <br>
> On 2018-11-02 10:37, Hans Nilsson R wrote:<br>
>> Hi,<br>
>><br>
>> Try<br>
>><br>
>> 5> ssh:daemon(1234, [{system_dir,...}, {shell,fun(Usr,Hst) -> spawn(fun() -> io:format("Hello ~p ~p~n",[Usr,Hst]), L1 = io:get_line("&& "), io:format("Got ~p~n", [L1]) end) end}]).<br>
>> {ok,<0.110.0>}<br>
>> 6><br>
>><br>
>> Sorry for the one-liner. The fun() a bit edited, I hope I got it right:<br>
>><br>
>>     fun(Usr,Hst) -><br>
>>            spawn(fun() -><br>
>>                     io:format("Hello ~p ~p~n",[Usr,Hst]),<br>
>>                     L1 = io:get_line("&& "),<br>
>>                     io:format("Got ~p~n", [L1])<br>
>>                  end)<br>
>>     end<br>
>><br>
>><br>
>> Note the option shell and the spawn, it is essential.<br>
>> You don't need the subsystem option.  The user_dir option defaults to the $HOME/.ssh of the user that started erl.<br>
>><br>
>> Now in bash:<br>
>><br>
>> ~$ ssh -p 1234 localhost<br>
>> Hello "USERNAME" {{127,0,0,1},60088}<br>
>> && some command<br>
>> Got "some command\n"<br>
>> Connection to localhost closed.<br>
>> ~$<br>
>><br>
>> Hope this helps.<br>
>> /Hans<br>
>><br>
>><br>
>><br>
>> On 11/2/18 10:05 AM, Mattsson, Tommy wrote:<br>
>>> Hi,<br>
>>><br>
>>> First time writer here on the erlang questions list :)<br>
>>><br>
>>><br>
>>> I am wondering if anyone knows about how the erlang ssh handles I/O? More details can be found below.<br>
>>><br>
>>><br>
>>> Erlang version: 21.0<br>
>>><br>
>>><br>
>>><br>
>>> Start of SSH server on testing (Windows) machine:<br>
>>><br>
>>> application:ensure_all_started(ssh),<br>
>>> Options = [{system_dir, filename:join(SSHPath, "daemon")}, {user_dir, ?DIR}, {subsystems, [ssh_sftpd:subsystem_spec([{cwd, SSHPath}])]}],<br>
>>><br>
>>> ssh:daemon(?ipaddr, ?port, Options]).<br>
>>><br>
>>> Test module:<br>
>>> -module(sshtest).<br>
>>> sshIO() -><br>
>>>    io:format("test1~n"),<br>
>>>    io:format("test2\n"),<br>
>>>   test3.<br>
>>><br>
>>><br>
>>> Test run from my own machine:<br>
>>>> ssh $IPADDR 'sshtest:sshIO().'<br>
>>> test3<br>
>>><br>
>>><br>
>>> For some reason any io:format/io:fwrite does not travel back over the SSH connection. If I connect to some Linux machine that already has a (non-erlang) SSH server running and I try to run some random bash script then any echo I have in the script will
 travel back over the SSH connection.<br>
>>><br>
>>> A test I did with a bash script towards a Linux server,<br>
>>> Bash script (~/test.sh):<br>
>>><br>
>>> echo "test1"<br>
>>><br>
>>> echo "test2"<br>
>>><br>
>>> echo "test3"<br>
>>><br>
>>><br>
>>> Test run from my own machine:<br>
>>>> ssh $IPADDR ./test.sh<br>
>>><br>
>>> test1<br>
>>><br>
>>> test2<br>
>>><br>
>>> test3<br>
>>><br>
>>> This is how I'd like it to work.<br>
>>><br>
>>><br>
>>> I have been googling and reading the documentation for the ssh and related modules to no avail in regards to finding a solution to this problem.<br>
>>><br>
>>> Other than this I/O problem the ssh connection works perfectly for me =<br>
> <br>
>>><br>
>>> Hopefully someone here on the list has some insight into how this works.<br>
>>><br>
>>> Thankful for any help I can get :)<br>
>>> Best regards,<br>
>>><br>
>>> Tommy<br>
>>><br>
>>><br>
>>><br>
>>><br>
>>><br>
>>><br>
>>> _______________________________________________<br>
>>> erlang-questions mailing list<br>
>>> erlang-questions@erlang.org<br>
>>> <a href="http://erlang.org/mailman/listinfo/erlang-questions" id="LPlnk531602" class="OWAAutoLink" previewremoved="true">
http://erlang.org/mailman/listinfo/erlang-questions</a><br>
>>><br>
>><br>
>><br>
>><br>
>> _______________________________________________<br>
>> erlang-questions mailing list<br>
>> erlang-questions@erlang.org<br>
>> <a href="http://erlang.org/mailman/listinfo/erlang-questions" id="LPlnk193770" class="OWAAutoLink" previewremoved="true">
http://erlang.org/mailman/listinfo/erlang-questions</a><br>
>><br>
> <br>
<br>
</div>
</span></font></div>
</div>
</div>
</body>
</html>