Forum > Linux

npx not found (after install with nvm) [solved]

(1/4) > >>

Michael Collier:
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

Red_prig:
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)

Red_prig:
https://www.freepascal.org/docs-html/rtl/sysutils/getenvironmentvariable.html

For example, reading environment variables

Michael Collier:
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  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---    my_batchfile.Add('#!/bin/bash');    my_batchfile.Add('export PATH="$PATH:/home/user1/.nvm/versions/node/v21.7.3/bin/"');    my_batchfile.Add('npx -v');   
But this seems like a hack, is there a more elegant solution I wonder?

TRon:
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  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---unit Unit1; {$mode objfpc}{$H+} interface uses  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls; type   { TForm1 }   TForm1 = class(TForm)    Button1: TButton;    Memo1: TMemo;    Panel1: TPanel;    procedure Button1Click(Sender: TObject);  private    procedure info(const s: string);    procedure info(const s: string; const args: array of const);  public  end; var  Form1: TForm1; implementation {$R *.lfm} uses  process;  { TForm1 } procedure TForm1.Button1Click(Sender: TObject);const  cmd_bash  = '/bin/bash';  cmd_test = './test';var  rc_result: string;begin  info('>$ %s -c %s', [cmd_bash, cmd_test]);  if RunCommand(cmd_bash, ['-c', cmd_test], rc_result) then  begin    info('output:');    info(rc_result);  end  else info('error running command %s -c %s', [cmd_bash, cmd_test]);end; procedure TForm1.info(const s: string);begin  Memo1.Append(S);  {$ifdef linux} // fix gtk bug not updating memo scroll  Memo1.selstart := MaxInt;  {$endif}end; procedure TForm1.info(const s: string; const args: array of const);begin  info(format(s, args));end;  (*program test; {$mode objfpc}{$H+} uses  sysutils; var  n : integer;begin  if GetEnvironmentVariableCount > 0 then    for n := 1 to GetEnvironmentVariableCount      do Writeln(n:3,' : ', GetEnvironmentString(n))  else writeln('no environment variables found');end.*)end. 
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).

Navigation

[0] Message Index

[#] Next page

Go to full version