Recent

Author Topic: npx not found (after install with nvm) [solved]  (Read 2040 times)

Michael Collier

  • Sr. Member
  • ****
  • Posts: 318
npx not found (after install with nvm) [solved]
« on: June 10, 2024, 08:05:05 pm »
Hi

I installed nodejs via Node Package Manager (npm) and could execute npx command via TProcess.

Recently I installed node via Node Version Manager (nvm) and now the TProcess reports it cannot find the command npx.

But I can execute the TProcess npx when my application is opened via a terminal window, rather then clicking the Desktop icon.

So I suspect the problem is to do with how linux sets environment-variables/paths but I haven't been able to get it working.

I noticed nvm modifies my ~./bashrc file, and the lazarus documentation says this will not be loaded
https://wiki.freepascal.org/Executing_External_Programs
 and .bashrc is not read by non-interactive shells unless you set the BASH_ENV environment variable

How do I set the BASH_ENV variable?, should I do this with another TProcess, or somehow configure my existing TProcess  (pipe?) ?

Or maybe there is another solution? Maybe modify the contents of a different system file in the same way ~./bashrc has been modified?

Note I have this working on windows by setting executable to 'c:\windows\system32\cmd.exe' and using /c with npx as a parameter. I tried similar with linux using '/bin/bash' and 'bin/sh' but no luck.

Maybe I'm close to a solution but just not the right combination of modifications..

Thanks,
Mike

« Last Edit: July 08, 2024, 06:05:48 pm by Michael Collier »

Red_prig

  • Full Member
  • ***
  • Posts: 152
Re: npx not found (after install with nvm)
« Reply #1 on: June 10, 2024, 09:59:16 pm »
You literally need to manually read the data and find the full path to the file, that is, imitate the behavior of the shell (PS: BASH_ENV refers to the '/bin/bash' itself and not the launch RunCommand)
« Last Edit: June 10, 2024, 10:03:13 pm by Red_prig »

Red_prig

  • Full Member
  • ***
  • Posts: 152
Re: npx not found (after install with nvm)
« Reply #2 on: June 10, 2024, 10:02:04 pm »

Michael Collier

  • Sr. Member
  • ****
  • Posts: 318
Re: npx not found (after install with nvm)
« Reply #3 on: June 10, 2024, 11:38:08 pm »
Thanks for that but I need to set the variable rather than reading it and can't find way to do it.

I tried playing with TProces.environment.add() but it never keeps my settings (it reads back the same string as it started with).

Temporary solution:

I've managed to save my command to a batch file, and executed that instead so now it works (the example below gets npx version number).

Code: Pascal  [Select][+][-]
  1.     my_batchfile.Add('#!/bin/bash');
  2.     my_batchfile.Add('export PATH="$PATH:/home/user1/.nvm/versions/node/v21.7.3/bin/"');
  3.     my_batchfile.Add('npx -v');  
  4.  

But this seems like a hack, is there a more elegant solution I wonder?


TRon

  • Hero Member
  • *****
  • Posts: 2865
Re: npx not found (after install with nvm)
« Reply #4 on: June 11, 2024, 06:05:10 am »
Does the following code output the correct environment variables in the memo for you or does the nxp command modify things on the fly ?

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     Button1: TButton;
  16.     Memo1: TMemo;
  17.     Panel1: TPanel;
  18.     procedure Button1Click(Sender: TObject);
  19.   private
  20.     procedure info(const s: string);
  21.     procedure info(const s: string; const args: array of const);
  22.   public
  23.   end;
  24.  
  25. var
  26.   Form1: TForm1;
  27.  
  28. implementation
  29.  
  30. {$R *.lfm}
  31.  
  32. uses
  33.   process;
  34.  
  35.  
  36. { TForm1 }
  37.  
  38. procedure TForm1.Button1Click(Sender: TObject);
  39. const
  40.   cmd_bash  = '/bin/bash';
  41.   cmd_test = './test';
  42. var
  43.   rc_result: string;
  44. begin
  45.   info('>$ %s -c %s', [cmd_bash, cmd_test]);
  46.   if RunCommand(cmd_bash, ['-c', cmd_test], rc_result) then
  47.   begin
  48.     info('output:');
  49.     info(rc_result);
  50.   end
  51.   else info('error running command %s -c %s', [cmd_bash, cmd_test]);
  52. end;
  53.  
  54. procedure TForm1.info(const s: string);
  55. begin
  56.   Memo1.Append(S);
  57.   {$ifdef linux} // fix gtk bug not updating memo scroll
  58.   Memo1.selstart := MaxInt;
  59.   {$endif}
  60. end;
  61.  
  62. procedure TForm1.info(const s: string; const args: array of const);
  63. begin
  64.   info(format(s, args));
  65. end;
  66.  
  67.  
  68. (*
  69. program test;
  70.  
  71. {$mode objfpc}{$H+}
  72.  
  73. uses
  74.   sysutils;
  75.  
  76. var
  77.   n : integer;
  78. begin
  79.   if GetEnvironmentVariableCount > 0 then
  80.     for n := 1 to GetEnvironmentVariableCount
  81.       do Writeln(n:3,' : ', GetEnvironmentString(n))
  82.   else writeln('no environment variables found');
  83. end.
  84. *)
  85. end.
  86.  

Note that the test program must be compiled with FPC (you can use Lazarus if you know how) and the executable placed in your project directory (or adjust the path to the test program in the example code).

You can ofc replace the test program with the nxp command (don't forget to add the -v option and/or full path to cmd_test variable in that case) but you said you already did that (and was not working for you).
« Last Edit: June 11, 2024, 06:09:02 am by TRon »

Michael Collier

  • Sr. Member
  • ****
  • Posts: 318
Re: npx not found (after install with nvm)
« Reply #5 on: June 11, 2024, 10:23:40 pm »
The output from the test program shows the PATH variable which does include path to where npx is located (or an alias for it).


PATH=/home/user1/.nvm/versions/node/v21.7.3/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games[


But the memo doesn't show it.

PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games


I think this will affect anyone wanting to execute a nodejs application from lazarus.
But I think the install process for nodejs makes a difference. When I used npm (node package manager) rather than nvm (node version manager) the PATH variable was set correctly for TProcess to use.


TRon

  • Hero Member
  • *****
  • Posts: 2865
Re: npx not found (after install with nvm)
« Reply #6 on: June 12, 2024, 12:51:20 am »
OK, thank you for the test.

In that case try replace
Code: Pascal  [Select][+][-]
  1. cmd_test = './test'
  2.  
with
Code: Pascal  [Select][+][-]
  1. cmd_test = 'source ~/.bashrc; ./test'
  2.  
and see if that helps.

It might be that you need to double quote the test command e.g.
Code: Pascal  [Select][+][-]
  1. cmd_test = '"source ~/.bashrc; ./test"'
  2.  

I am not always sure how RunCommand handles that.

Michael Collier

  • Sr. Member
  • ****
  • Posts: 318
Re: npx not found (after install with nvm)
« Reply #7 on: June 12, 2024, 01:24:59 am »
I executed the code without double quotes (error otherwise). Unfortunately using source didn't make a difference (I kinda thought it would though), the PATH variable is still missing the part that appears in a standard terminal.

Michael Collier

  • Sr. Member
  • ****
  • Posts: 318
Re: npx not found (after install with nvm)
« Reply #8 on: June 12, 2024, 03:48:05 am »
The following works..

Code: Pascal  [Select][+][-]
  1. cmd_test = 'export PATH="$PATH:/home/user1/.nvm/versions/node/v21.7.3/bin/"; npx -v' ;
  2.  

It finds npx in the updated PATH and prints out version number..

I tried with a more complex npx example and it worked too..

I'll try more tomorrow.. Looks promising.. Thanks :)

TRon

  • Hero Member
  • *****
  • Posts: 2865
Re: npx not found (after install with nvm)
« Reply #9 on: June 12, 2024, 09:54:39 am »
Unfortunately using source didn't make a difference (I kinda thought it would though), the PATH variable is still missing the part that appears in a standard terminal.
Hmz, I would have expected that to work as well.

Do you happen to know whether or not the sourcing of bashrc actually took place or that the command was skipped (e.g perhaps the "~" is not expanding properly, e.g then one could try replace with things like 'source "$HOME/bashrc"' (double quotes included as shown))

The following works..
Yes, that was indeed the next step to suggest  :)

If that is enough for you then that is ok as well. I would personally prefer for the bashrc to be 'included' in the same environment though as there might be other things that your programs depends on. It is always possible to start in interactive mode with -i bash option but I don't think that is going to make things easier.

I have not experimented enough with these things to know for sure.

PS: also note that there is a special crafted runcommand named runcommandindir that allows you to set the path to/of the executable and which you could perhaps use and get away with it. It all depends on whether or not the nxp command (or whatever it executes further along in the process) depends on the path to be set/be present. If it works then you could get rid of the whole bin/bash invocation. It is similar in nature as supplying the full path to the nxp command.
« Last Edit: June 12, 2024, 10:24:25 am by TRon »

MarkMLl

  • Hero Member
  • *****
  • Posts: 7069
Re: npx not found (after install with nvm)
« Reply #10 on: June 12, 2024, 11:45:31 am »
I tried playing with TProces.environment.add() but it never keeps my settings (it reads back the same string as it started with).

Remember that that only works in the context of the TProcess you've just created, and the program it is about to run.

It does not change anything else in the current program.

And- unlike DOS (can't speak for Windows here) unix has no way of changing a shell (environment) variable in a parent process.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

MarkMLl

  • Hero Member
  • *****
  • Posts: 7069
Re: npx not found (after install with nvm)
« Reply #11 on: June 12, 2024, 01:32:28 pm »
I installed nodejs via Node Package Manager (npm) and could execute npx command via TProcess.

Recently I installed node via Node Version Manager (nvm) and now the TProcess reports it cannot find the command npx.

But I can execute the TProcess npx when my application is opened via a terminal window, rather then clicking the Desktop icon.

So running from a shell session, what does

Code: Text  [Select][+][-]
  1. $ which npx
  2.  

and

Code: Text  [Select][+][-]
  1. $ file `which npx`
  2.  

return?

Note the usual convention there of a leading $ to indicate that you're running at a shell prompt as an unprivileged user.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Michael Collier

  • Sr. Member
  • ****
  • Posts: 318
Re: npx not found (after install with nvm)
« Reply #12 on: June 12, 2024, 09:52:06 pm »
From a terminal window..

$ which npx
/home/user1/.nvm/versions/node/v21.7.3/bin/npx

file `which npx`
/home/user1/.nvm/versions/node/v21.7.3/bin/npx: symbolic link to ../lib/node_modules/npm/bin/npx-cli.js


From the test program..

I tried variations as suggested but no luck. I'm pretty certain the source command is executing because if I deliberatley mis-spell the filename it reports an error (btw changed semicolon to && to get it to report error, also tried pipe | to see what happens).


MarkMLl

  • Hero Member
  • *****
  • Posts: 7069
Re: npx not found (after install with nvm)
« Reply #13 on: June 12, 2024, 10:37:40 pm »
/home/user1/.nvm/versions/node/v21.7.3/bin/npx: symbolic link to ../lib/node_modules/npm/bin/npx-cli.js

So now look what's at the start of that .js file. It's probably a shebang pointing directly at a binary rather than using the path, and while the kernel ** will honour that you can't rely on a TProcess doing so: it wants the name of an ELF file.

** Years (decades!) ago, I had to contend with somebody who insisted that "the UNIX way" was for the shebang to be processed by the shell, but as a result of that I can say that under at least some circumstances the Linux kernel handles it.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Michael Collier

  • Sr. Member
  • ****
  • Posts: 318
Re: npx not found (after install with nvm)
« Reply #14 on: June 13, 2024, 01:02:56 am »
Quote
So now look what's at the start of that .js file. It's probably a shebang pointing directly at a binary rather than using the path,

This is the content of the file..shebang line 1..
Code: Javascript  [Select][+][-]
  1. #!/usr/bin/env node
  2. require('../lib/cli.js')(process)
  3.  

 

TinyPortal © 2005-2018