18

I want to pass the environment variable named file_path to js file.

I am using the following syntax:

mongo --eval "var file_path='$file_path'" < aggregation.js

Output:

MongoDB shell version: 3.2.9-rc0
connecting to: test

Note:

It does not execute aggregation.js file. only it pass the argument.

Penny Liu
  • 15,447
  • 5
  • 79
  • 98
Shubham Pardeshi
  • 191
  • 1
  • 1
  • 5
  • 1
    For anyone else surprised that mongo doesn't support this - there's a request for it here: https://jira.mongodb.org/browse/SERVER-4895 – Matthew Mar 05 '19 at 10:48

6 Answers6

20

This worked for me:

mongo --eval "var my_var = '$MY_VAR'" my_script.js

Leave out the <. mongo will process any remaining arguments on the command line as files to be executed/interpreted, but apparently combining the shell input redirect with --eval causes the javascript namespace to be reset.

I assume but cannot confirm that this is because filenames passed as arguments are processed via the load() mechanism, which according to https://docs.mongodb.com/v3.2/reference/method/load/, behaves as follows:

After executing a file with load(), you may reference any functions or variables defined the file from the mongo shell environment.

Karen B
  • 2,693
  • 1
  • 17
  • 19
9

According to this commit, it looks like there's a native method called _getEnv() that can do it for you.

const username = _getEnv('DB_USERNAME')
const password = _getEnv('DB_PASSWORD')
// use the username and password
  • Since MongoDB 5.0 `mongo` shell is deprecated and replaced by `mongosh` https://docs.mongodb.com/manual/reference/program/mongo/#mongodb-binary-bin.mongo Which does not support _getEnv as far as I can tell. Any suggestions? – Tony I. Dec 14 '21 at 10:00
  • 1
    @ReFruity, `mongosh` is also a Node.js shell, so simply use [process.env](https://nodejs.org/api/process.html#processenv): `process.env["DB_USERNAME"]` – Wernfried Domscheit Jan 06 '22 at 06:50
7

Since Mongo 4.0.5 it is possible to utilize some of the new admin functions to load text files and execute programs. So you can write a Javascript function to execute a shell script that provides the value of an environment variable:

function getEnvValue(envVar, defVal) {
   var ret= run("sh", "-c", `printenv ${envVar} >/tmp/${envVar}.txt`);
   if (ret != 0) return defVal;
   return cat(`/tmp/${envVar}.txt`)
}

And then using it like this:

db.createCollection("myCol",
 { capped: true,
   size: getEnvValue('MYCOL_MAX_SIZE_GB', 2)*1024*1024*1024
});

This relies on the host shell but was acceptable in my case (Docker).

Was also trying to read the environ directly:

cat('/proc/self/environ').split('\0') # Doesn't work

but it only gets the first variable. I guess because of the null characters...

Raedwald
  • 46,613
  • 43
  • 151
  • 237
Premik
  • 71
  • 1
  • 2
  • 2
    I have used your approach but I had to had the --null parameter to printenv to avoid new line. `printenv --null ${envVar} >/tmp/${envVar}.txt` – Ausiàs Armesto May 01 '20 at 14:40
  • The `run()` seems to be undocumented, see [Native Methods](https://docs.mongodb.com/manual/reference/method/js-native/) Do you think it is save to use it? – Wernfried Domscheit Aug 20 '20 at 09:20
5

Looks like Native Method shellGetEnv() has been added meanwhile, see MongoDB GitHub

Function is available (thanks to @orgads):

_getEnv("PATH")

However, it is not documented and there is no statement yet whether it may be used by end-user or only as internal command.

The new MongoDB Shell, mongosh, is a fully functional JavaScript and Node.js 14.x REPL environment, thus you can access environment variables with process.env, e.g.

process.env["PATH"]
Wernfried Domscheit
  • 54,457
  • 9
  • 76
  • 110
0

There's a suggestion from the mongo change request:

alias mongo="export | sed 's/declare -x /env./' > shell.js; mongo $@; rm shell.js;"

Then in ~/mongorc.js:

var env = {};
load('shell.js');
Matthew
  • 10,361
  • 5
  • 42
  • 54
0

In case of Mongo 6 use process.env:

$ export A='a"a'
$ mongosh --quiet --eval 'console.log(process.env.A)'
a"a

Before 6.x:

$ q_A=`jq --arg v "$A" -n '$v'`
$ mongosh --quiet --eval "console.log($q_A)"
a"a

By the way, the mongo image (docker) comes with jq, although that might change.

x-yuri
  • 16,722
  • 15
  • 114
  • 161