Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2023-05

Why does RunCommand not produce the correct output?

7 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Bo Berglund

I am trying to create a function to list the available serial ports on a Linux device. But I have trouble getting commands which work on a terminal to also work when run from my console program.

When I run this conmmand in the terminal I get the correct reply:

$ ls -l /sys/class/tty/*/device/driver | grep -v "platform/drivers/serial8250" |
awk '{print $9}' | awk -F'/' '{print "/dev/" $5}'

/dev/ttyAMA0

But when I use RunCommand() in FPC it does not work long line wrapped by newsreader):

program listserialports;
{$mode objfpc}{$H+}
uses
  baseunix, classes, sysutils, process;
function ListSerialPorts: integer;
var
  ListCmd: TProcessString;
  OutData: string;
begin
  Result := 0;
  ListCmd := 'ls -l /sys/class/tty/*/device/driver | grep -v
"platform/drivers/serial8250" | awk ''{print $9}'' | awk -F''/'' ''{print
"/dev/" $5}''';
  Writeln('Command: ' + ListCmd); //To see what is actally sent to Linux
  RunCommand(ListCmd, OutData);
  Writeln(OutData);
end;
begin
  ListSerialPorts;
  Writeln('Done');
end.

I see the command being executed but there is an empty output. If I copy the dislayed command and paste it in and run it I get the result as shown above. So there should be no typo in the command line, right? Still no output...

What can I do?
(I have created a shellscript with the same command string and it runs just fine and prints the data on screen.
But I need the function in order to populate a control with the output inside a GUI program once thus function works.

Bo Berglund Developer in Sweden

Reply by email

Unknown author
to Bo Berglund: I am trying to create a function to list the available serial ports on a Linux device.…

As mentioned in another post, you'll need to run a shell, (whether it be bash or another system provided shell), in order to process the commands.  If you run the commands directly, there is no shell interpretation, and the | which passes the output of one command to the input of the next one won't function as expected,

I don't know what environment processes commands if you run the commands without a shell environment, it could be FPC, or it could be something buried in the linux environment, I've never bothered to look up the answer, but it certainly won't have the redirection capability of the linux shells provided by the system, and actually, can behave differently, depending on which shell is used.

You could just add the line:

#!/bin/bash

to the first line of your script, then just call the script from your program.

Alternatively, you could call the bash command, and pass the command to it that way, either one should get you the output you desire.

Bo Berglund wrote 51 lines
I am trying to create a function to list the available serial ports on a Linux device. But I have trouble getting commands which work on a terminal to also work when run from my console program. When I run this conmmand in the terminal I get the correct reply: $ ls -l /sys/class/tty/*/device/driver | grep -v "platform/drivers/serial8250" | awk '{print $9}' | awk -F'/' '{print "/dev/" $5}' /dev/ttyAMA0 But when I use RunCommand() in FPC it does not work long line wrapped by newsreader): program listserialports; {$mode objfpc}{$H+} uses baseunix, classes, sysutils, process; function ListSerialPorts: integer; var ListCmd: TProcessString; OutData: string; begin Result := 0; ListCmd := 'ls -l /sys/class/tty/*/device/driver | grep -v "platform/drivers/serial8250" | awk ''{print $9}'' | awk -F''/'' ''{print "/dev/" $5}'''; Writeln('Command: ' + ListCmd); //To see what is actally sent to Linux RunCommand(ListCmd, OutData); Writeln(OutData); end; begin ListSerialPorts; Writeln('Done'); end. I see the command being executed but there is an empty output. If I copy the dislayed command and paste it in and run it I get the result as shown above. So there should be no typo in the command line, right? Still no output... What can I do? (I have created a shellscript with the same command string and it runs just fine and prints the data on screen. But I need the function in order to populate a control with the output inside a GUI program once thus function works.

Reply by email

Bo Berglund
to Unknown author
Travis Siegel wrote 9 lines
You could just add the line: #!/bin/bash to the first line of your script, then just call the script from your program. Alternatively, you could call the bash command, and pass the command to it that way, either one should get you the output you desire.

I did already create a script "listserial" that does the extraction: (long line split by newsreader)

-----------------------------
#!/bin/bash
SERLIST=$(ls -l /sys/class/tty/*/device/driver | grep -v "platform/drivers/serial8250" | awk '{print $9}' | awk -F'/' '{print "/dev/" $5}')
echo $SERLIST
-----------------------------

This successfully lists the available serial ports by their device name, which can be used to open the port using the built-in serial unit functionality.

Of course I *could* call the script from the program but I wanted it all be within the FPC program itself...

But it can be done by calling the standalone script file of course...

Bo Berglund Developer in Sweden

Reply by email

Unknown author
to Bo Berglund

Well, you could use the infile and outfile redirect functionality.  I don't know how it's done in fpc, but the manual should get you the proper syntax.  Simply redirect the text output to a file or buffer, then redirect the input file buffer as well, and feed the output from the first command to the input of the next one.  I've seen it done, but it was quite some time ago, and I don't remember the specifics.  With this method, it would take multiple steps, but you could then control the process from start to finish.  The only issue is you'll have to put in the full path of the commands you're running, since there won't be any shell running to use the path for locating the programs you want.

In all likelihood, the programs you're using will be in /usr/bin, but unfortunately, there's no guarantee of that.

Bo Berglund wrote 32 lines
On Mon, 1 May 2023 14:25:28 -0400, Travis Siegel via fpc-pascal wrote: > You could just add the line: > > #!/bin/bash > > to the first line of your script, then just call the script from your > program. > > Alternatively, you could call the bash command, and pass the command to > it that way, either one should get you the output you desire. I did already create a script "listserial" that does the extraction: (long line split by newsreader) ----------------------------- #!/bin/bash SERLIST=$(ls -l /sys/class/tty/*/device/driver | grep -v "platform/drivers/serial8250" | awk '{print $9}' | awk -F'/' '{print "/dev/" $5}') echo $SERLIST ----------------------------- This successfully lists the available serial ports by their device name, which can be used to open the port using the built-in serial unit functionality. Of course I *could* call the script from the program but I wanted it all be within the FPC program itself... But it can be done by calling the standalone script file of course...

Reply by email

Bo Berglund
to Bo Berglund: I am trying to create a function to list the available serial ports on a Linux device.…
Bo Berglund wrote 12 lines
I am trying to create a function to list the available serial ports on a Linux device. But I have trouble getting commands which work on a terminal to also work when run from my console program. When I run this conmmand in the terminal I get the correct reply: $ ls -l /sys/class/tty/*/device/driver | grep -v "platform/drivers/serial8250" | awk '{print $9}' | awk -F'/' '{print "/dev/" $5}' /dev/ttyAMA0 But when I use RunCommand() in FPC it does not work.

I have asked on the Lazarus forum too and there I gotr a solution for my base problem so I do not need to use complex commands vua RunCommand. See this thread:

https://forum.lazarus.freepascal.org/index.php/topic,63256.msg478804.html#msg478804

Bo Berglund Developer in Sweden

Reply by email