Recent

Author Topic: How to set an environment variable for the current process at runtime?  (Read 7396 times)

Manlio

  • Full Member
  • ***
  • Posts: 164
  • Pascal dev
The following code lists the environment variables of the current process:

Code: Pascal  [Select][+][-]
  1.   for i := 0 to GetEnvironmentVariableCount-1 do
  2.     Log(GetEnvironmentString(i));
  3.  

The result is something like this:                                                           

Code: [Select]
TMPDIR=/var/folders/mp/gx458m3x0c5__tsxrgcczs880000gn
SHELL=/bin/bash
HOME=/Users/admin

... and several more lines like that

Now, I would like to add one more environmental variable to the list, e.g. MYNAME=my-value

I only want to add this environmental variable to the current running process. This is useful, for example, to pass information to a dylib.(1)

On Windows this can be done with SetEnvironmentVariable() and on Linux, I read, there is SetEnv().

So the question is, how do I do it on MacOS?

I know about the "export" bash command, so I tried to execute the command from within my program, like this:

Code: Pascal  [Select][+][-]
  1. Uses unix;
  2.  
  3.   fpsystem('export MYNAME=my-value');
  4.  

After doing that, however, if I use again GetEnvironmentVariableCount() and GetEnvironmentString(i), nothing has changed, my name/value pair is not there.

So, can someone kindly show me how to do it?

(1) I'm asking this question because I'm trying to use the VLC library on MacOS, and before I can call certain functions in the dylib files, I must provide an environment variable named VLC_PLUGIN_PATH containing the full path of the plugins folder.

manlio mazzon gmail

dbannon

  • Hero Member
  • *****
  • Posts: 2802
    • tomboy-ng, a rewrite of the classic Tomboy
Re: How to set an environment variable for the current process at runtime?
« Reply #1 on: February 13, 2022, 05:40:02 am »
Hmm, it would be very useful to do this but I am note sure its possible. 

(on linux)
SetEnv is a bash command, so not something you can use within a lazarus application. Except as you did with 'export', in both cases the setting will apply to the new process created, not the one in your running process.

Does not seem to be anything in osutilsh which is where I would expect it to be if it existed.

I guess you want to set this var AFTER the app has started and had a think about it ?  And I also guess you are are aware that the normal way to set a var for an app (in eg bash) is -

MYSPECIALVAR="SomeValue" ./myApp <enter>

Davo

edit: MacOS ? Oh dear, probably need to put something in the app bundle like the above.
« Last Edit: February 13, 2022, 05:42:05 am by dbannon »
Lazarus 3, Linux (and reluctantly Win10/11, OSX Monterey)
My Project - https://github.com/tomboy-notes/tomboy-ng and my github - https://github.com/davidbannon

trev

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2023
  • Former Delphi 1-7, 10.2 user
Re: How to set an environment variable for the current process at runtime?
« Reply #2 on: February 13, 2022, 05:51:24 am »
Here's a good explanation which I saved a few years ago:

Quote
When a UNIX process is created by the kernel, the environment variables are put in its address space; typically near the top of the stack. They are not stored in the kernel data structures for the process. And thus there are no system calls for getting or setting those variables.

trev

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2023
  • Former Delphi 1-7, 10.2 user
Re: How to set an environment variable for the current process at runtime?
« Reply #3 on: February 13, 2022, 05:59:30 am »
So the question is, how do I do it on MacOS [sic]?
So, can someone kindly show me how to do it?

On macOS, the normal way to do it is to set any needed environment variables in the LSEnvironment property of your application's Info.plist file.

See: https://developer.apple.com/documentation/bundleresources/information_property_list/lsenvironment

Manlio

  • Full Member
  • ***
  • Posts: 164
  • Pascal dev
Re: How to set an environment variable for the current process at runtime?
« Reply #4 on: February 13, 2022, 03:02:52 pm »
On macOS, the normal way to do it is to set any needed environment variables in the LSEnvironment property of your application's Info.plist file.
See: https://developer.apple.com/documentation/bundleresources/information_property_list/lsenvironment

Yes, I can set environment variables via Info.plist, but I would still need to be able to do so at runtime, once I know things like the folder where the program is running from, and what other program may or may not be installed on the machine.

Also let me raise a loud WARNING that might save someone a lot of time and headache: After I change the data in Info.plist and run the program again, NOTHING HAPPENS because macOS apparently caches the Info.plist data the first time you run the program! So you go on making changes, testing them, and get wrong results because you think the program is using the Info.plist file which is on the disk, but instead macOS is still using the previous cached version!!!

I didn't find any way to prevent this, and only rebooting the program, or renaming/copying the whole folder that contains the program, forces macOS to load the new version of Info.plist.

I wish I had known that before spending two hours to figure this out....
manlio mazzon gmail

trev

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2023
  • Former Delphi 1-7, 10.2 user
Re: How to set an environment variable for the current process at runtime?
« Reply #5 on: February 14, 2022, 01:04:47 am »
Yes, I can set environment variables via Info.plist, but I would still need to be able to do so at runtime, once I know things like the folder where the program is running from, and what other program may or may not be installed on the machine.

As explained above this is not possible from within the application - it's just the way UNIX is.

Thaddy

  • Hero Member
  • *****
  • Posts: 14382
  • Sensorship about opinions does not belong here.
Re: How to set an environment variable for the current process at runtime?
« Reply #6 on: February 14, 2022, 10:20:19 am »
Yes, I can set environment variables via Info.plist, but I would still need to be able to do so at runtime, once I know things like the folder where the program is running from, and what other program may or may not be installed on the machine.

As explained above this is not possible from within the application - it's just the way UNIX is.
Well, it should be: https://phoenixnap.com/kb/linux-set-environment-variable
Will add example later if it works. :-X
Note that on Windows, if you add anything at runtime, the old environment is discarded and a new one is created.
On linux one should edit the hidden file ~/.bashrc, but that needs sudo rights or a program that has sufficient rights.
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

MarkMLl

  • Hero Member
  • *****
  • Posts: 6692
Re: How to set an environment variable for the current process at runtime?
« Reply #7 on: February 14, 2022, 11:38:09 am »
As explained above this is not possible from within the application - it's just the way UNIX is.

Up to a point, Lord Copper. In principle a process can manipulate its own variables, which I think it what OP was asking. After all, that's how a shell sets its PATH variable.

/However/, any assumption that a process will make use of the changed variable to e.g. locate a library is unsafe.

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

Thaddy

  • Hero Member
  • *****
  • Posts: 14382
  • Sensorship about opinions does not belong here.
Re: How to set an environment variable for the current process at runtime?
« Reply #8 on: February 14, 2022, 12:27:58 pm »
Editing .bashrc seems to work, but I don't know if it works on Apples. (My Mac Mini died as you all know, or in coma)
At least a Linux version under Debian works (Raspi and x86_64), provided admin rights.
It only needs a TFileStream or better a TStringlist.
« Last Edit: February 14, 2022, 12:32:57 pm by Thaddy »
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

PascalDragon

  • Hero Member
  • *****
  • Posts: 5486
  • Compiler Developer
Re: How to set an environment variable for the current process at runtime?
« Reply #9 on: February 14, 2022, 03:24:16 pm »
On linux one should edit the hidden file ~/.bashrc, but that needs sudo rights or a program that has sufficient rights.

Editing one's own .bashrc does never require root rights, cause that file is supposed to be editable by the owning user (and ~ points to the home directory of the user that started the process).

But editing the file will only work for shells that do indeed parse ~/.bashrc. For example a shell like zsh won't touch that file by default.

winni

  • Hero Member
  • *****
  • Posts: 3197
Re: How to set an environment variable for the current process at runtime?
« Reply #10 on: February 14, 2022, 05:08:00 pm »
Hi!

If you change the .bashrc you have to reread it.

This is  done in the current session with

. ~/.profile


Danger! If you just delete a line this will not change the environment var.

Winni

Thaddy

  • Hero Member
  • *****
  • Posts: 14382
  • Sensorship about opinions does not belong here.
Re: How to set an environment variable for the current process at runtime?
« Reply #11 on: February 14, 2022, 05:57:41 pm »
@Sarah and @Winni,

Yes I know, but it was the question if it could be done (changing/adding to the environment from running code).
more or less a proof of concept.
My idea is not ready to be in production, but then again:
It can be done.

Regards, tdk.
« Last Edit: February 14, 2022, 06:54:17 pm by Thaddy »
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

MarkMLl

  • Hero Member
  • *****
  • Posts: 6692
Re: How to set an environment variable for the current process at runtime?
« Reply #12 on: February 14, 2022, 06:34:02 pm »
If you change the .bashrc you have to reread it.

This is  done in the current session with

. ~/.profile


No it won't. In the general case those are distinct files used by different shells.

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

Thaddy

  • Hero Member
  • *****
  • Posts: 14382
  • Sensorship about opinions does not belong here.
Re: How to set an environment variable for the current process at runtime?
« Reply #13 on: February 14, 2022, 06:52:57 pm »
Correct.
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

MarkMLl

  • Hero Member
  • *****
  • Posts: 6692
Re: How to set an environment variable for the current process at runtime?
« Reply #14 on: February 14, 2022, 08:48:32 pm »
Editing one's own .bashrc does never require root rights, cause that file is supposed to be editable by the owning user (and ~ points to the home directory of the user that started the process).

I'm slightly uncomfortable with that. I can't put a finger on it, but I think I've seen legitimate situations where a user did not (and should not) have access to that file... and that's particularly the case where a daemon was started as e.g. root:root and then was relaxed to a nominal uid:gid like nobody:nogroup or daemon:root.

In any event, OP specifically said

Quote
I only want to add this environmental variable to the current running process. This is useful, for example, to pass information to a dylib.(1)

so I don't think that .bashrc or .profile is really relevant.

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

 

TinyPortal © 2005-2018