# How to get environment variables HOME and USER in Prolog cgi

**URL:** <https://swi-prolog.discourse.group/t/how-to-get-environment-variables-home-and-user-in-prolog-cgi/5499>\
**Category:** Predicate\
**Created:** [June 16, 2022, 9:55am UTC](https://swi-prolog.discourse.group/t/how-to-get-environment-variables-home-and-user-in-prolog-cgi/5499 "2022-06-16T09:55:18Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![kuniaki.mukai](https://avatars.discourse-cdn.com/v4/letter/k/c67d28/32.png) [@kuniaki.mukai](https://swi-prolog.discourse.group/u/kuniaki.mukai)\
**Post date:** [June 16, 2022, 9:55am UTC](https://swi-prolog.discourse.group/t/how-to-get-environment-variables-home-and-user-in-prolog-cgi/5499/1 "2022-06-16T09:55:18Z")

</div>

How to get environment variables HOME and USER in Prolog cgi ? As getenv/2 does’nt work for this purpose, I used an ad hoc way which uses prolog\_load\_context/2 hinted by a sample code by Jan somewhere sometime. Now I would like to know more appropriate way to get the two environmental variables. Thanks in advance.

---

<div class="post-metadata">

**Author:** ![EricGT](https://avatars.discourse-cdn.com/v4/letter/e/f1d935/32.png) [@EricGT](https://swi-prolog.discourse.group/u/EricGT)\
**Post date:** [June 16, 2022, 10:06am UTC](https://swi-prolog.discourse.group/t/how-to-get-environment-variables-home-and-user-in-prolog-cgi/5499/2 "2022-06-16T10:06:55Z")

</div>

> [@kuniaki.mukai](#):
>
> Prolog cgi

What do you mean by `Prolog cgi`? I suspect you are referring to some library or example code.  
Can you give a reference.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [June 16, 2022, 10:11am UTC](https://swi-prolog.discourse.group/t/how-to-get-environment-variables-home-and-user-in-prolog-cgi/5499/3 "2022-06-16T10:11:34Z")

</div>

What is wrong with getenv/2? If it is an environment variable it should work. As @EricGT says, a bit more context may help.

---

<div class="post-metadata">

**Author:** ![kuniaki.mukai](https://avatars.discourse-cdn.com/v4/letter/k/c67d28/32.png) [@kuniaki.mukai](https://swi-prolog.discourse.group/u/kuniaki.mukai)\
**Post date:** [June 16, 2022, 10:43am UTC](https://swi-prolog.discourse.group/t/how-to-get-environment-variables-home-and-user-in-prolog-cgi/5499/4 "2022-06-16T10:43:00Z")

</div>

The prolog cgi (scipt?) is called from Javascrit like this, which I borrowed  
from the net more than 10 years ago without knowing anything about Ajax.  
I am afraid it is too old style nowadays, but I would like to keep using this as far as it works. My purpose is to hide home and user from sources which are so far on several host and plat forms.

```prolog
# shell script calling Prolog code

#! /bin/sh
USER=cantor
HOME=/Users/${USER}

SWIPL=$HOME/bin/swipl
PACLIB=${HOME}/devel/zdd/prolog
PACSETUP=${PACLIB}/pac.pl
SCRIPT=${PACLIB}/util/web.pl
CGI=${PACLIB}/util/cgi.pl
MAIN='web:cgi_main'
${SWIPL} -q -s ${PACSETUP} -s ${CGI} -s ${SCRIPT} -g ${MAIN} -t halt

```

```prolog
# Ajax 

function httpPostRequest(target_url, post_data, functionReference) {
    try {
        if(window.XMLHttpRequest) {
            httpObj = new XMLHttpRequest();
        } else if(window.ActiveXObject) {
            httpObj = new ActiveXObject("Microsoft.XMLHTTP");
        } else {
           httpObj = false;
        }
    } catch(e) { httpObj = false; }
    if(! httpObj) { httpObjGenerateFail(); }
    // タイマーをセット
    if (timerId == null) 
	{ timerId = setInterval('timeoutCheck()', 1000);}
    else 
    { clearInterval(timerId); timerId = null; }
    httpObj.open("POST", target_url, true);
    httpObj.onreadystatechange = function() {
        if (httpObj.readyState == 4) {
            clearInterval(timerId);
            if (httpObj.status == 200) {
                functionReference(httpObj.responseText);
            } else {
                alert(httpObj.status + ' : ' + httpObj.statusText);
                return false;
            }
        }
    }
    timeout_sec = timeout_sec_init; // reset timer counter [2010/02/16]
    httpObj.send(post_data);
}

```

---

<div class="post-metadata">

**Author:** ![jamesnvc](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jamesnvc/32/14_2.png) [@jamesnvc](https://swi-prolog.discourse.group/u/jamesnvc)\
**Post date:** [June 16, 2022, 11:31am UTC](https://swi-prolog.discourse.group/t/how-to-get-environment-variables-home-and-user-in-prolog-cgi/5499/5 "2022-06-16T11:31:35Z")

</div>

getenv/2 should work like that; I tried running a shell script like the one you have there around a simple prolog program that just outputs the environment variables and it acted as expected.

What does the Prolog code that’s trying to get the environment variables look like?

---

<div class="post-metadata">

**Author:** ![kuniaki.mukai](https://avatars.discourse-cdn.com/v4/letter/k/c67d28/32.png) [@kuniaki.mukai](https://swi-prolog.discourse.group/u/kuniaki.mukai)\
**Post date:** [June 16, 2022, 11:41am UTC](https://swi-prolog.discourse.group/t/how-to-get-environment-variables-home-and-user-in-prolog-cgi/5499/6 "2022-06-16T11:41:33Z")

</div>

Thanks. I will try it later on a linux host to see it works like that. As far as on macOS, I never have seen it works, which has been a mystery for me for a long time.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [June 16, 2022, 11:53am UTC](https://swi-prolog.discourse.group/t/how-to-get-environment-variables-home-and-user-in-prolog-cgi/5499/7 "2022-06-16T11:53:10Z")

</div>

> [@kuniaki.mukai](#):
>
> ```prolog
> USER=cantor
> HOME=/Users/${USER}
> 
> ```

Shouldn’t this be `export USER=cantor`, etc.?

---

<div class="post-metadata">

**Author:** ![jamesnvc](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jamesnvc/32/14_2.png) [@jamesnvc](https://swi-prolog.discourse.group/u/jamesnvc)\
**Post date:** [June 16, 2022, 12:26pm UTC](https://swi-prolog.discourse.group/t/how-to-get-environment-variables-home-and-user-in-prolog-cgi/5499/8 "2022-06-16T12:26:01Z")

</div>

> [@kuniaki.mukai](#):
>
> As far as on macOS, I never have seen it works, which has been a mystery for me for a long time.

I actually just ran it on macos & it worked as expected…

> **Script + execution**
>
> ```prolog
> ⟣─ ~/tmp
> cat foo.sh
> #!/bin/sh
> 
> USER=cantor
> HOME=/Users/${USER}
> 
> swipl -q -l foo.pl -g main -t halt
> ⟣─ ~/tmp
> cat foo.pl
> :- module(foo, [main/0]).
> 
> main :-
> getenv('HOME', Home),
> getenv('USER', User),
> format("Hello; HOME=~w; USER=~w~n", [Home, User]).
> ⟣─ ~/tmp
> ./foo.sh
> Hello; HOME=/Users/cantor; USER=cantor
> ⟣─ ~/tmp
> uname -a
> Darwin bishop.local 21.5.0 Darwin Kernel Version 21.5.0: Tue Apr 26 21:08:37 PDT 2022; root:xnu-8020.121.3~4/RELEASE_ARM64_T6000 arm64
> 
> ```

> [@jan](#):
>
> Shouldn’t this be `export USER=cantor`, etc.?

I would have thought so, but it seems like `USER` and `HOME` specifically get inherited without having to `export`.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [June 16, 2022, 1:04pm UTC](https://swi-prolog.discourse.group/t/how-to-get-environment-variables-home-and-user-in-prolog-cgi/5499/9 "2022-06-16T13:04:36Z")

</div>

> [@jamesnvc](#):
>
> I would have thought so, but it seems like `USER` and `HOME` specifically get inherited without having to `export`.

A little experiment confirmed what I thought: if a variable is already exported and set in the shell the environment is updated. If the variable is newly set in the shell it is not added to the environment.

My suspicion is that @kuniaki.mukai runs the web server as a service and this service does not set USER and HOME.

---

<div class="post-metadata">

**Author:** ![kuniaki.mukai](https://avatars.discourse-cdn.com/v4/letter/k/c67d28/32.png) [@kuniaki.mukai](https://swi-prolog.discourse.group/u/kuniaki.mukai)\
**Post date:** [June 16, 2022, 1:14pm UTC](https://swi-prolog.discourse.group/t/how-to-get-environment-variables-home-and-user-in-prolog-cgi/5499/10 "2022-06-16T13:14:32Z")

</div>

> [@jan](#):
>
> My suspicion is that @kuniaki.mukai runs the web server as a service and this service does not set USER and HOME.

Yes, I issued the command  
% brew services restart httpd

---

<div class="post-metadata">

**Author:** ![kuniaki.mukai](https://avatars.discourse-cdn.com/v4/letter/k/c67d28/32.png) [@kuniaki.mukai](https://swi-prolog.discourse.group/u/kuniaki.mukai)\
**Post date:** [June 16, 2022, 2:03pm UTC](https://swi-prolog.discourse.group/t/how-to-get-environment-variables-home-and-user-in-prolog-cgi/5499/11 "2022-06-16T14:03:07Z")

</div>

I have tested the case for prolog cgi called from Ajax on a LINUX machine.

Prolog getenv(‘HOME’, \_) seems also to fail to get the HOME, which is the same as on macOS.

:- getenv(‘HOME’, Home), open(’/home/mukai/Desktop/home\_value’, write, S),  
write(S, Home), close(S).

It seems a platform independent problem, and perhaps it is just a bug  
which lives somewhere in my codes.

---

<div class="post-metadata">

**Author:** ![jamesnvc](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jamesnvc/32/14_2.png) [@jamesnvc](https://swi-prolog.discourse.group/u/jamesnvc)\
**Post date:** [June 16, 2022, 2:29pm UTC](https://swi-prolog.discourse.group/t/how-to-get-environment-variables-home-and-user-in-prolog-cgi/5499/12 "2022-06-16T14:29:02Z")

</div>

If you try changing the script to

```prolog
export USER="..."
export HOME="..."

```

does that work?

---

<div class="post-metadata">

**Author:** ![kuniaki.mukai](https://avatars.discourse-cdn.com/v4/letter/k/c67d28/32.png) [@kuniaki.mukai](https://swi-prolog.discourse.group/u/kuniaki.mukai)\
**Post date:** [June 16, 2022, 2:51pm UTC](https://swi-prolog.discourse.group/t/how-to-get-environment-variables-home-and-user-in-prolog-cgi/5499/13 "2022-06-16T14:51:10Z")

</div>

No, it does not.

Now I am thinking it may be natural in a sense that USER and HOME are undefined in a CGI, because USER may be defined to be www in the httpd.conf on a host. My ad hoc way using ‘prolog\_load\_context/1’ seems more suitable way to get the CGI owner’s HOME and USER.

---

<div class="post-metadata">

**Author:** ![kuniaki.mukai](https://avatars.discourse-cdn.com/v4/letter/k/c67d28/32.png) [@kuniaki.mukai](https://swi-prolog.discourse.group/u/kuniaki.mukai)\
**Post date:** [June 16, 2022, 4:59pm UTC](https://swi-prolog.discourse.group/t/how-to-get-environment-variables-home-and-user-in-prolog-cgi/5499/14 "2022-06-16T16:59:26Z")

</div>

Additional information: on linux,  
printenv at terminal shows HOME and USER correctly as expected, but  
printenv at prolog script under httpd via javascript does not include neither HOME nor USER. So I am giving up hope to get HOME and USER by prolog getenv.

---

<div class="post-metadata">

**Author:** ![peter.ludemann](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/peter.ludemann/32/48_2.png) [@peter.ludemann](https://swi-prolog.discourse.group/u/peter.ludemann)\
**Post date:** [June 16, 2022, 5:26pm UTC](https://swi-prolog.discourse.group/t/how-to-get-environment-variables-home-and-user-in-prolog-cgi/5499/15 "2022-06-16T17:26:20Z")

</div>

If you’re running as a daemon (or from `initd`, `chron`, `service`, etc), does it make sense to have any environment variables by default? After all, these things are often started by root. (There’s also no attached tty, of course, which is why there’s `/var/log`.)

The easiest way is to set environment variables in a shell script and then use `exec "$@"`. You can find some suggestions for how to do this by searching stackoverflow for [daemon environment variables], but some of the answers I found are not good code, so you might want to ask again here when you’ve found an answer that seems to fit your situation.

---

<div class="post-metadata">

**Author:** ![kuniaki.mukai](https://avatars.discourse-cdn.com/v4/letter/k/c67d28/32.png) [@kuniaki.mukai](https://swi-prolog.discourse.group/u/kuniaki.mukai)\
**Post date:** [June 16, 2022, 5:58pm UTC](https://swi-prolog.discourse.group/t/how-to-get-environment-variables-home-and-user-in-prolog-cgi/5499/16 "2022-06-16T17:58:17Z")

</div>

Thank for suggestion, which tells me that things are much more complex than I thought. My purpose is to use the exactly same SWI-Prolog script on macOS also on a linux host machine with a simple local config information at the home directory, on which I am not a root user. For Prolog codes it is simple task provided that only USER and HOME are known. Thank you for preventing me from further efforts who is not good at such investigation.

---

<div class="post-metadata">

**Author:** ![kuniaki.mukai](https://avatars.discourse-cdn.com/v4/letter/k/c67d28/32.png) [@kuniaki.mukai](https://swi-prolog.discourse.group/u/kuniaki.mukai)\
**Post date:** [June 16, 2022, 6:14pm UTC](https://swi-prolog.discourse.group/t/how-to-get-environment-variables-home-and-user-in-prolog-cgi/5499/17 "2022-06-16T18:14:40Z")

</div>

This is a local configuration for my mac at home. Editing a few lines around commented lines, this configuration works on the remote linux machine with the same prolog script provided HOME and USER are availabe for getenv. I setenved by ‘parsing’ information from prolog\_load\_context.

```prolog
~/.config/cgi-config.pl
:- module(config, [cgi_eqns/1, pac_directories/1]).
cgi_eqns([
	home_html	= $(home) + '/public_html',
	home_cgi_bin = $(home) + '/public_html/cgi-bin',
	host = 'http://localhost',
%	host = 'http://webedit.sfc.keio.ac.jp',
	host_user	= $(host) + ':/~' + $(user),
	host_cgi_bin = $(host_user) + '/cgi-bin',
	dvipdfmx	= '/Library/TeX/texbin/dvipdfmx',
%	dvipdfmx	= '/usr/local/bin/dvipdfmx'
	platex = '/Library/TeX/texbin/platex',
%	platex = ' /usr/local/bin/platex',
	pdf2ps = '/usr/local/bin/pdf2ps',
%	pdf2ps = '/usr/bin/pdf2ps',
	snapshot	= $(home)+'/Desktop/snapshot',
	exercise_js_name = 'http_request.js'
			]).

pac_directories(
		[	(pac_root : []) -
			 [	test:test,
				:(prolog) -
					[	pac : pac,
						util	: util,
						zdd : zdd,
						tmp : tmp,
						gb : "util/grobner",
						other	: other
					]]]
			   ).

```
