Forum > Linux
npx not found (after install with nvm) [solved]
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