Register forum user name Search FAQ

Gammon Forum

Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, making threats, or asking for money, are spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the password reset link.

Due to spam on this forum, all posts now need moderator approval.

 Entire forum ➜ MUSHclient ➜ Lua ➜ Using utils.shellexecute for ping results?

Using utils.shellexecute for ping results?

It is now over 60 days since the last post. This thread is closed.     Refresh page


Posted by AdInfinitum   (74 posts)  Bio
Date Thu 02 Aug 2018 04:55 PM (UTC)
Message
Currently, I have an alias as follows:

<aliases>
  <alias
   match="^ping (.*?) (.*?)$"
   enabled="y"
   regexp="y"
   send_to="12"
   sequence="100"
  >
  <send>n = "C:/MUSHClient/pingresults.txt"
pingmin, pingmax, pingavg = nil, nil, nil

os.execute("ping %2 > " .. n .. " &")

for line in io.lines(n) do
    if string.find(line, "Minimum =") then
        pingmin = string.match(line, "Minimum = (%d+ms)")
    end
    if string.find(line, "Maximum = ") then
        pingmax = string.match(line, "Maximum = (%d+ms)")
    end
    if string.find(line, "Average =") then
        pingavg = string.match(line, "Average = (%d+ms)")
    end
end

if pingmin and pingmax and pingavg then
    Send("%1 @r{@x111Ping to @W%2 @x111Min: @w" .. pingmin .. " @x111Avg: @w" .. pingavg .. " @x111Max: @w" .. pingmax .. "@r}$C")
else
    Send("%1 @r{@x111Unsuccessful ping to @w%2@r}$C")
end

os.remove(n)</send>
  </alias>
</aliases>


This works properly, except it opens up a command window, which freezes game play for a few seconds while it executes the command.

Last night, I came across utils.shellexecute, and thought this might be a great substitute for os.execute, so I decided to play with it. However, I cannot seem to get it to work. If I try:


utils.shellexecute("ping", "aardmud.org")


... then it works. But I need to store the results in a text file, and when I try:


utils.shellexecute("ping", "%2 > " .. n .. " &", GetInfo(68), "open", 0)


... in place of the os.execute, it doesn't seem to generate the text file, evidenced the by error I get that there is nothing to be read.

I've also tried, to no avail:

utils.shellexecute("cmd", "ping %2 > " .. n .. " &", GetInfo(68), "open", 0)


Is there a way I can accomplish what I want? Or is this just a fruitless venture?
Top

Posted by Nick Gammon   Australia  (23,133 posts)  Bio   Forum Administrator
Date Reply #1 on Thu 02 Aug 2018 08:03 PM (UTC)
Message
See: https://www.gammon.com.au/scripts/doc.php?lua=utils.shellexecute

You haven't exactly done what is suggested there (near the bottom). In particular use the /C parameter.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by AdInfinitum   (74 posts)  Bio
Date Reply #2 on Thu 02 Aug 2018 11:19 PM (UTC)
Message
Ah, for some reason, it hadn't clicked that the /C was required. Now the ping properly works, but instead of waiting for the results to be put into the pingresults.txt file, it attempts to read it right away.

What way would you suggest is the best way to handle that situation? I could easily use wait, but that would require me to put some arbitrary number of seconds that may or may not be long enough. If possible, I'd rather have it wait until the ping command was finished.

Maybe if I do a loop checking if the file exists?
Top

Posted by Nick Gammon   Australia  (23,133 posts)  Bio   Forum Administrator
Date Reply #3 on Fri 03 Aug 2018 05:37 AM (UTC)
Message
I've confronted this issue in the past.

Quote:

This works properly, except it opens up a command window, which freezes game play for a few seconds while it executes the command.


...

Quote:

... but instead of waiting for the results to be put into the pingresults.txt file, it attempts to read it right away.


Well, do you want to wait or not?

You could delete the file, run the command, and then loop checking if the file has been created (which will, of course, introduce a delay).

It's not that you want the file created, too, it's that you want it to be finished written to. If you wait for the file to appear, it might have 0 bytes in it.

These aren't easy problems to solve. You might delete the file, write to a different file, then rename it when done. This isn't so much a MUSHclient issue, it's the way that reality works. Things don't happen instantly. Either you wait for them to finish, or you work around that.

Possibly start the file writing, and then, using a timer, check every half second or so for the (renamed) file to appear. This could be done with the "wait" module.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by AdInfinitum   (74 posts)  Bio
Date Reply #4 on Fri 03 Aug 2018 08:45 PM (UTC)
Message
Regarding waiting, I did need it to wait to finish writing to the log. I wound up using wait.make in order to accomplish it, setting it at 5 seconds, figuring if it wasn't finished pinging in 5 seconds, then I had a really bad connection anyway. Here's the finished product now:

require "wait"

n = "C:/MUSHClient/pingresults.txt"
pingmin, pingmax, pingavg = nil, nil, nil

wait.make(function ()

    assert(utils.shellexecute("cmd", "/C ping %2 > " .. n .. " &", GetInfo(68), "open", 0))

    wait.time(5)
    
    for line in io.lines(n) do
        if string.find(line, "Minimum =") then
            pingmin = string.match(line, "Minimum = (%d+ms)")
        end
        if string.find(line, "Maximum = ") then
            pingmax = string.match(line, "Maximum = (%d+ms)")
        end
        if string.find(line, "Average =") then
            pingavg = string.match(line, "Average = (%d+ms)")
        end
    end

    if pingmin and pingmax and pingavg then
    &#9;Send("%1 @r{@x111Ping to @W%2 @x111Min: @w" .. pingmin .. " @x111Avg: @w" .. pingavg .. " @x111Max: @w" .. pingmax .. "@r}$C")
    else
        Send("%1 @r{@x111Unsuccessful ping to @w%2@r}$C")
    end

    os.remove(n)
end)


The %1 and %2 are channel and site you're pinging, respectively, if anyone is interested in using it.

Thanks for guiding me to the right path - this provides uninterrupted play while I ping something, and not having to worry about a window opening up has been a blessing! I wish I had known about this sooner!
Top

Posted by Nick Gammon   Australia  (23,133 posts)  Bio   Forum Administrator
Date Reply #5 on Sat 04 Aug 2018 12:26 AM (UTC)
Message
You should probably do an io.open to check the file exists, otherwise it would crash if it doesn't.

io.lines raises an error if it can't open the file. Instead you can use io.open and check for a nil return.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Fiendish   USA  (2,534 posts)  Bio   Global Moderator
Date Reply #6 on Sun 05 Aug 2018 03:36 PM (UTC)
Message
Quote:
I wound up using wait.make in order to accomplish it, setting it at 5 seconds


But you don't want to always wait 5 seconds. Make it wait only 0.1 seconds in a loop until either the file is written or 5 seconds has elapsed from when you started. That way you'll get your response as soon as possible.

https://github.com/fiendish/aardwolfclientpackage
Top

Posted by Nick Gammon   Australia  (23,133 posts)  Bio   Forum Administrator
Date Reply #7 on Sun 05 Aug 2018 10:41 PM (UTC)
Message
You don't want a half-written file, so waiting a bit of extra time would help, whatever "extra" means in this context. Possibly waiting until the file size has ceased to change, however the file size may only change when the output is flushed to disk, so that might not mean anything.

Possibly you could detect if the size is greater than some minimum, then it has probably been written to. (Because of the flushing aspect, the minimum might well be zero).

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by AdInfinitum   (74 posts)  Bio
Date Reply #8 on Mon 06 Aug 2018 01:48 PM (UTC)
Message
I think what I can do in this case is loop until the file size is greater than 1 kb. The file is made at the start, but it's empty. It doesn't get written to until the ping has completed. As such, as long as the file size is greater than 1 kb, I should be okay. For all intents and purposes, I could even increase that to about 80 kb to make sure there's something of substance actually written.

Thanks for the great feedback!
Top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


22,955 views.

It is now over 60 days since the last post. This thread is closed.     Refresh page

Go to topic:           Search the forum


[Go to top] top

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.