Exiting a runShellCommandAsynchronously() process - Arduion Yun

Hey!

Let me first start by defining my goal, I want to use runShellCommandAsynchronously() which runs MADPLAY to play some beautiful music, but I want to be able to use a button to stop the music.

I was not able to find out how to exit runShellCommandAsynchronously() in my arduino sketch, I tried to use process.close(); however to my avail it does not work.

Anyone would care to shed some insight on how it may be possible to exit a Linux shell command while it is still being executed.

Keep in mind I will not be able to automate the exit by using a python script.

Thanks guys 8)

shimmyjimmy: Hey!

Let me first start by defining my goal, I want to use runShellCommandAsynchronously() which runs MADPLAY to play some beautiful music, but I want to be able to use a button to stop the music.

I was not able to find out how to exit runShellCommandAsynchronously() in my arduino sketch, I tried to use process.close(); however to my avail it does not work.

Anyone would care to shed some insight on how it may be possible to exit a Linux shell command while it is still being executed.

Keep in mind I will not be able to automate the exit by using a python script.

Thanks guys 8)

@shimmyjimmy, when you run a program as runShellCommandAsynchronously() this means you run it in the background. As the documentation says:

 [i]Quote:[/i]
Unlike run(), runAsynchronously() is not-blocking. Your sketch will continue to run while the Linux process [b]runs in the background.[/b]

When you run your program, it registers a Process ID. If you run kill ${Process_ID}, it will stop your program.

Read this: Using the command line for communication with SSH and cURL

If this seems too much, remove the power from the YUN.

Jesse

The key, of course, is getting the process ID so you can kill it. It's too bad that runAsynchronously() doesn't return the process ID.

I suppose one could write a script to search the running task list to get the PID, and then kill it. That script could then be run by another Process invocation from the sketch.

I just tried to use the Process.close() method and it works. Can you share your code so we can give a look to it?

Test code:

#include <Process.h>

  Process p;

void setup() {
  // Initialize Bridge
  Bridge.begin();

  // Initialize Serial
  Serial.begin(9600);

  // Wait until a Serial Monitor is connected.
  while (!Serial);
 
  p.begin("ping");
  p.addParameter("www.google.com");

  p.runAsynchronously();
  Serial.println("Started");

}

void loop() {
  if (p.available() > 0) Serial.println((char)p.read());
  if (Serial.read() == 'C') p.close();  //if you send C it closes the ping command
  delay(10);
}

Hey so here is my code for playing music through the usb port, i was hoping to find a solution that did not require an automated script

#include <Process.h>
Process p;
int pin = 9; 

void setup() {
Bridge.begin();// put your setup code here, to run once:
pinMode(9,INPUT);
pinMode(13,OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
p.runShellCommandAsynchronously("madplay /mnt/sda1/Sounds/bloop.mp3");
while(p.running()){
  digitalWrite(13,HIGH);
  if(digitalRead(9) == HIGH){
    p.close();
  }
}
}

I actually got it work! thank you very much guys! I just should have use p.begin() rather than using a shell command straight off the bat

:smiley_cat:

ShapeShifter: The key, of course, is getting the process ID so you can kill it. It's too bad that runAsynchronously() doesn't return the process ID.

I suppose one could write a script to search the running task list to get the PID, and then kill it. That script could then be run by another Process invocation from the sketch.

@ShapeShifter, Most programming languages have a means to get the process ID. With bash and perl, the shorthand is $$. So, it would look like, PID=$ in bash and $PID=$ in perl.

With python, google: python get pid

os.getpid() https://docs.python.org/2/library/os.html

Jesse

Of course. But getpid() just gets the PID of the current task. But that really only helps if we write that task so it commits suicide (and there are easier ways for the current task to terminate itself.) What I was talking about is murder - a script that finds the task of interest and kills it. That script could be called from a Process object to stop the asynchronous process. It would be simpler if the Process object could return the PID of the task it created, so that it is available on the sketch side of the bridge. (The Linux side of the bridge code certainly has access to the PID of the task it created, but it does not appear to communicate that to the sketch side.)

But it's pretty much a moot point since Process.close() seems to terminate the process on its own without having to resort to such shenanigans.

ShapeShifter: ::::SNIP::::

But it's pretty much a moot point since Process.close() seems to terminate the process on its own without having to resort to such shenanigans.

@ShapeShifter, I keep forgetting that I've been doing this for sometime and people don't know what I know.

A standard practice for system administration is to write the PID to a file in tmp. Such as:

echo $PID > /var/run/my_name.pid
chmod 600 /var/run/my_name.pid

As such, any program with the correct permision could get that PID and issue a CLI

kill $PID

YES. This is a moot point. ;-)

Jesse