Recent

Author Topic: Why this command not working with RunCommand?  (Read 678 times)

rnfpc

  • Jr. Member
  • **
  • Posts: 91
Why this command not working with RunCommand?
« on: July 14, 2019, 10:19:33 am »
I am working on Debian Stable Linux system with fpc version 3.0.0. On my system, the command 'alias' produces following output:
Code: Pascal  [Select]
  1. alias ll='ls -ltrk'
  2. alias ls='ls --color=auto'
I also try to run it from following pascal file:
Code: Pascal  [Select]
  1. {$mode objfpc}
  2. uses Process;
  3. var s: ansistring;
  4. begin
  5.         if RunCommand('alias', [], s)
  6.         then writeln(s);
  7. end.
Though above file compiles and runs without any error, it produces no output.

Similarly, following also does not work:
Code: Pascal  [Select]
  1. if RunCommand('/bin/bash',['-c','alias'],s)
  2. then writeln(s);

Following code, where I try to run an alias, also does not work:
Code: Pascal  [Select]
  1. if RunCommand('/bin/bash',['-c','ll'],s)
  2. then writeln(s);

'll' is an alias on my system as shown above.

Following code from https://wiki.freepascal.org/Executing_External_Programs#.28Process..29RunCommand works all right:

Code: Pascal  [Select]
  1. if RunCommand('/bin/bash',['-c','echo $PATH'],s)
  2. then writeln(s);

Following summarizes my problem:
Code: Pascal  [Select]
  1. if RunCommand('/bin/bash',['-c','echo $PATH'],s) then writeln('res1:',s);
  2. if RunCommand('/bin/bash',['-c','alias'],s) then writeln('res2:',s);
  3. if RunCommand('/bin/bash',['-c','ll'],s) then writeln('res3:',s);
  4. if RunCommand('echo $PATH', [], s) then writeln('res4:',s);
  5. if RunCommand('alias', [], s) then writeln('res5:',s);
  6. if RunCommand('ll', [], s) then writeln('res6:',s);
produces following output:
Code: Pascal  [Select]
  1. res1:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
  2.  
  3. res2:
First line gives correct output, 2nd line gives blank output; all others give no output.

Where is the problem and how can I run 'alias' and 'll' commands from pascal files?
« Last Edit: July 14, 2019, 10:34:32 am by rnfpc »

lucamar

  • Hero Member
  • *****
  • Posts: 2264
Re: Why this command not working with RunCommand?
« Reply #1 on: July 14, 2019, 10:36:45 am »
Try like this:
Code: Pascal  [Select]
  1. if RunCommand('/bin/bash',['-c','alias'],s, [poUsePipes, poWaitOnExit])
  2. then writeln(s);

and the same for the rest.

ETA: All those lines that give no output? That's because they are not "programs" one executes but bash commands. You must pass them to the executable "bash" so that it can interpret and execute them.
« Last Edit: July 14, 2019, 10:41:28 am by lucamar »
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus 2.0.4/2.0.6  - FPC 3.0.4 on:
(K|L)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

rnfpc

  • Jr. Member
  • **
  • Posts: 91
Re: Why this command not working with RunCommand?
« Reply #2 on: July 14, 2019, 12:34:16 pm »
Try like this:
Code: Pascal  [Select]
  1. if RunCommand('/bin/bash',['-c','alias'],s, [poUsePipes, poWaitOnExit])
  2. then writeln(s);
and the same for the rest.

This does not work. The error is:
Code: Pascal  [Select]
  1. Error: Wrong number of parameters specified for call to "RunCommand"

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 7833
Re: Why this command not working with RunCommand?
« Reply #3 on: July 14, 2019, 12:36:05 pm »
  • 4 and 5 can't work. If it is not a physical binary on disk, runcommand can't run it without bash -c (1..3).
  • 1 works.
  • 2  also works (positive result, but empty). Probably aliases don't inherit from their parent. So there is nothing to show. So the "new" instance of bash doesn't have it, since it is only running in the parent of the binary that does the runcommand
  • 3 is then a logical consequence of 2. Is not defined, so failed to run

I had hoped that defining the aliases in .bashrc would help (so that bash would interpret .bashrc it on aux shell execution), but it doesn't. Anyway, this requires some research in how to force bash to interpret some file with aliases on secundary/auxilary execution.

IOW it is a bash, not a runcommand problem.

To get you started, a quick search yielded : https://unix.stackexchange.com/questions/1496/why-doesnt-my-bash-script-recognize-aliases
« Last Edit: July 14, 2019, 12:39:51 pm by marcov »

rnfpc

  • Jr. Member
  • **
  • Posts: 91
Re: Why this command not working with RunCommand?
« Reply #4 on: July 14, 2019, 12:38:49 pm »
ETA: All those lines that give no output? That's because they are not "programs" one executes but bash commands. You must pass them to the executable "bash" so that it can interpret and execute them.

Following using bash also does not work:
Code: Pascal  [Select]
  1. if RunCommand('/bin/bash',['-c','alias'],s) then writeln('res2:',s);
  2. if RunCommand('/bin/bash',['-c','ll'],s) then writeln('res3:',s);

lucamar

  • Hero Member
  • *****
  • Posts: 2264
Re: Why this command not working with RunCommand?
« Reply #5 on: July 14, 2019, 08:03:07 pm »
Code: Pascal  [Select]
  1. if RunCommand('/bin/bash',['-c','alias'],s, [poUsePipes, poWaitOnExit])
  2. then writeln(s);

This does not work. The error is:
Error: Wrong number of parameters specified for call to "RunCommand"

Sorry for the delay, been out most of the day. It should not give you that error; it's a perfectly valid invocation of RunCommand(). I've just tested with this code:
Code: Pascal  [Select]
  1. resourcestring
  2.   sNotFound = 'Can''t find "%s"';
  3.   sCmdToRun = '%s %s';
  4.   sCmdError = 'Error: RunCommand() failed';
  5.   sResult   = 'Result:' + LineEnding +
  6.               '%s' + LineEnding;
  7.   sNoResult = 'Result: Nothing to display.';
  8.  
  9. procedure TMainForm.btDoTestClick(Sender: TObject);
  10. var
  11.   cmd: String = '';
  12.   cmdRes: String = '';
  13. begin
  14.   cmd := FindDefaultExecutablePath('bash');
  15.   if cmd = '' then
  16.     ShowMessageFmt(sNotFound, ['bash'])
  17.   else begin
  18.     Memo.Text := Format(sCmdToRun, [cmd, '-c alias']);
  19.     if not RunCommand(cmd, ['-c', 'alias'], cmdRes, [poStderrToOutPut]) then
  20.       Memo.Lines.Add(sCmdError);
  21.     if cmdRes.IsEmpty then
  22.       Memo.Lines.Add(sNoResult)
  23.     else
  24.       Memo.Lines.Add(sResult, [cmdRes]);
  25.   end;
  26. end;

and it compiles and runs without fault. See attached image.

As you can see invoking 'bash -c alias' in this machine also produces nothing so Marco seems to be right: aliases are not inherited by the child process. Bad luck!

To be clear: It's not that the command doesn't work, it's that there are no aliases so it outputs nothing.
« Last Edit: July 14, 2019, 08:10:34 pm by lucamar »
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus 2.0.4/2.0.6  - FPC 3.0.4 on:
(K|L)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

del

  • Full Member
  • ***
  • Posts: 158
Re: Why this command not working with RunCommand?
« Reply #6 on: December 06, 2019, 01:48:27 am »
I get around a lot of these problems by just calling a shell script using TProcess. Which is fine for hobby stuff, but for commercial stuff it would involve including the scripts (.sh for Linux, .ps1 for Windows) in the distribution. Is this ever done? Does anybody know of this ever being done in a "commercial" context?

winni

  • Hero Member
  • *****
  • Posts: 716
Re: Why this command not working with RunCommand?
« Reply #7 on: December 06, 2019, 02:33:13 am »
Hi!

Linux alias is bound to a  specific user. If user A set his aliases in the ~/.bashrc or  ~/.bash_aliases then they are not valid for user B.

With runcommand you start a new instance of the bash with user "unknown" or user "lazarus" - I don't know. But this bash does not know anything about your aliases.

But you could read the bashrc of the needed user and look what aliases there are stored.
But a lot of work - just for an alias.

So if you start a bash with lazarus - it is not your bash!

Winni

winni

  • Hero Member
  • *****
  • Posts: 716
Re: Why this command not working with RunCommand?
« Reply #8 on: December 06, 2019, 03:56:23 am »
Hi!

The test to figure  out the name of the user of the bash, started by lazarus.

With the linux command who you can get a lot of infos: who is logged in, start time, hostname etc

This shows the boot time:

Code: Pascal  [Select]
  1. if RunCommand('/bin/bash',['-c','/usr/bin/who -b'],s) then showMessage(s);

There is an undocumented feature for who to figure out as whom you are logged in:

Code: Bash  [Select]
  1. who am I

But this is a feature with the ability for a lot of jokes. who with two parameters returns always the user name. So you can enter who MyGirl loves....

Anyway, if you use it with the bash started by lazarus

Code: Pascal  [Select]
  1. if RunCommand('/bin/bash',['-c','/usr/bin/who am I'],s) then showMessage(s);

The resulting string is empty.

So the user name is ''. And not rnfpc or lucamar.

Winni
« Last Edit: December 06, 2019, 04:01:50 am by winni »

MarkMLl

  • Hero Member
  • *****
  • Posts: 603
Re: Why this command not working with RunCommand?
« Reply #9 on: December 06, 2019, 09:06:00 am »
Sorry for another very late response. I was playing with some related stuff the other day and found that  bash -c  is very picky when it is parsing multiple parameters. The way to explore this appears to be by issuing a command like

Code: [Select]
$ bash -c ls -l

where you might find that the -l option isn't correctly passed to ls, and then comparing it with

Code: [Select]
$ bash -c 'ls -l'

which is what appears to work. Doing that allowed me to sort out a TProcess problem (I was attempting to start Lazarus with --pcp so that I could debug a child program).

That explains the failed command that @lucamar reported, and the successful run of  who  by @winni.

Code: [Select]
$ who
markMLl  tty7         2019-11-26 08:04 (:0)
markMLl  pts/0        2019-11-26 08:04 (:0)

$ who am i
markMLl  pts/7        2019-12-06 07:54 (:0)

$ bash -c who am i
markMLl  tty7         2019-11-26 08:04 (:0)
markMLl  pts/0        2019-11-26 08:04 (:0)

$ bash -c 'who am i'
markMLl  pts/7        2019-12-06 07:54 (:0)

MarkMLl



Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 7833
Re: Why this command not working with RunCommand?
« Reply #10 on: December 06, 2019, 09:33:35 am »
yes, shell commandlines should be passed as one parameter.