How to submit several inputs to a shell?


I’d like to convert the following command, which works fine from a terminal window, to the Xojo shell:
mailx -r -s “Subject”

When I execute this in the terminal, it then asks for more input (the body of the message, followed by a line with just “.” to finish the body, and a third line with “Cc:” (which I’d like to keep empty). In Xojo, I don’t know how to replicate this “additional input”. I tried 2 techniques; both failed:

1: a synced method:

Var s As new Shell

Var cmd As String="mailx -r <from address> -s ""Subject"" <target address>"+EndOfLine+"Test body"+EndOfLine+"."+EndOfLine+EndOfLine
s.Execute cmd
MessageBox "ExitCode="+s.ExitCode.ToString+"; Result="+s.Result

Here, the shell tries to execute each line as individual command, and the first, main, command returns “ExitCode=2; Result=Null message body; hope that’s ok”.

2: an asynchronous method:

Var s As new Shell

AddHandler s.Completed,AddressOf ShellResult
AddHandler s.DataAvailable,AddressOf ShellResult
Var cmd As String="mailx -r <from address> -s ""Subject"" <target address>"
s.Execute cmd
s.WriteLine "Test body"
s.WriteLine "."
s.WriteLine ""
MessageBox "ExitCode="+s.ExitCode.ToString+"; Result="+s.Result

In this case, the result I’m getting is “Shell result: ExitCode=137; Result=”. I couldn’t find information about the error code 137, other than “out of memory”, which doesn’t sound correct.

I’m puzzled. To continue my debug attempts, I first have to understand which way is correct (async or sync?). Ideas, please?

What is wrong with using an smtpsocket ?

My app is running on the server itself. I tried with CURLMBS, both using or the address of the server, and I got a connexion refused error each time.
Then I thought maybe I can’t connect with a socket to the same server my app is running on and attempted using a shell.

2 days dealing with weird errors and behaviours, for which even Google has no answer, is exhausting. It all started with a server denying my app to send emails (which worked up to that), so I thought about configuring my own server using Postfix. But I’m not a Unix/server expert and have encountered a lot of dead ends in these 2 days. I’ll take a one-day break.

Thank you.

Perhaps you need to open the port that supports smtp. That would explain the connexion refused.

I use smtpsocket all the time in my web apps.

To directly answer this question, you need to use the “Interactive” ExecuteMode. There should be an example project for interactive mode included with your Xojo installation.

With that said, it seems like you are trying to get around the wrong problem here. In another reply you state you are doing this because you get a connection refused error using other techniques. That sounds like trying the wrong port or something. What happens if you try the Xojo example project “SimpleSendEmail” in Examples > Comunication > Email ?

1 Like

In your async shell code, you’re trying to treat it as if it were synchronous. To make async work, you need the shell to be in a broader scope than just a variable in the method, and you need to feed it the additional information in the DataAvailable event. You get the final result in the Completed event.


It’s already done:
~$ sudo ufw app info “Postfix”

Profile: Postfix

Title: Mail server (SMTP)

Description: Postfix is a high-performance mail transport agent



I’m using CURLMBS. Could it be they are different? I know smtp but CURL is new to me (it just happened to work).


I tried too. In this case, I didn’t get any DataAvailable or Completed event; the shell just waited for more input (which I couldn’t feed).

Thanks for putting me back on the right track; with all I’ve done this week-end, I’ve lost my path :wink:
I’ll try the example this evening (no time since then).

That didn’t work either (I don’t recall exactly which error I got, since I’ve had so many different attempts).

What did work, though, is this syntax (qt is a string holding a quote and nd is a dictionary holding parameters): "echo “+qt+“Test”+qt+” | mailx -r “+qt+“Me”+qt+” -s “+qt+nd.Value(“Subject”)+qt+” "+nd.Value(“Address”)

However, I’m facing another issue where some servers won’t “talk with me” (some work). I need to add a PTR record, but my registrar seem to provide all fields but PTR. My issue is a never ending nightmare.

Thanks for your answers.

Can’t you add to DNS records ?

Answering the original question about multiple inputs to a shell, I do it by writing a temporary script file and executing it.

Dim tmp As FolderItem, ScriptFile As FolderItem, ts As TextOutputStream

tmp = SpecialFolder.Temporary
If tmp = Nil Then Return

ScriptFile = tmp.Child("your-filename-here.bat")
ts = ScriptFile.CreateTextFile
If ts = Nil Then Return

ts.WriteLine "1st line"
ts.WriteLine "2nd line"
ts.WriteLine "3rd line"


I also agree that there may be better ways to send email.


I use this with success as well.

Also, you can launch a bash/zsh as the “.execute” command in Async mode and then interact with the shell as if you were typing in the info using theShell.WriteLine. When you’re done, just send “exit”.

My DNS are already working, but the blacklisting servers (like tell I should add a PTR record, which is the opposite of a DNS record. And it looks like I should add the PTR to my server rather than at the registrar.
Being a self-taught guy has some downsides :face_with_diagonal_mouth:

Good idea, indeed. I’m assuming each line is feeding the asked inputs.

Good tips on this thread!


So, I tested, and I’m getting an error code 22 (after a hang of several seconds). I tried both port 25 and port 587.
For the user/password, I’ve created a user on the server just for that. Postfix is configured to allow existing users to send mails (at least, it works from the ssh terminal). That’s the user I’m passing in the Xojo example project.