2

In our CentOS server, the env variable NODE_OPTIONS was set to a wrong value. I checked some possible files such as /etc/environment, /etc/profile, but no luck. I also tried to grep it from /etc/, still no luck. This makes me upset.

I even tried this: https://unix.stackexchange.com/a/154971/92712

Surprised to find that there's no such variable in the output. But it is in

printenv NODE_OPTIONS 
set | grep NODE_OPTIONS
echo $NODE_OPTIONS

(shell is bash)

Is there any way to get in which file the this NODE_OPTIONS comes from?


More info:

$ node -v
node: invalid value for NODE_OPTIONS (unterminated string)

$ echo $NODE_OPTIONS --max-old-space-size=5120"

$ cat /etc/environment
export NODE_OPTIONS="--max-old-space-size=5120"


Update:

Thanks @ilkkachu

$ declare -p NODE_OPTIONS
declare -x NODE_OPTIONS="--max-old-space-size=5120\" "

update 2: The extra double quotation appears in env output too:

$ env
NODE_OPTIONS=--max-old-space-size=5120"

update 3: Thanks @Johan Myréen

$ od -c /etc/environment
0000000  \n   e   x   p   o   r   t       N   O   D   E   _   O   P   T
0000020   I   O   N   S   =   "   -   -   m   a   x   -   o   l   d   -
0000040   s   p   a   c   e   -   s   i   z   e   =   5   1   2   0   "
0000060       #   i   n   c   r   e   a   s   e       t   o       5   g
0000100   b  \n  \n
0000103
ilkkachu
  • 138,973
Nick
  • 1,127
  • @ilkkachu Thanks. I removed -l option, still no luck. – Nick Aug 11 '21 at 11:51
  • ah ok, I should have read better. I thought you didn't find where it was defined. But it looks like the question is why the value is broken. You seem to have a trailing double quote there in the output of echo $NODE_OPTIONS, but no leading one, is that right? You could also use declare -p NODE_OPTIONS to have Bash print it in an unambiguous form. – ilkkachu Aug 11 '21 at 12:07
  • 1
    The file /etc/environment should contain simple NAME=VALUE pairs. Remove the export. (I don't think this solves your problem, though.) – Johan Myréen Aug 11 '21 at 12:28
  • @ilkkachu You're right. There's an extra trailing quote in echo $NODE_OPTIONS. I suspect the value comes from another file, but cannot find it. – Nick Aug 11 '21 at 12:34
  • To check if the file /etc/environment does not contain any extra control characters, run od -c /etc/environment. – Johan Myréen Aug 11 '21 at 13:19
  • @JohanMyréen Thanks. I added the od command output to the update. Is that look good? – Nick Aug 11 '21 at 13:24
  • 1
    @Nick The file /etc/environment really should contain only NAME=VALUE pairs and nothing else. No export and no comments. The file is not parsed by a shell. – Johan Myréen Aug 11 '21 at 13:28
  • @Nick Remove the comment including the # character, and it will solve your problem. While you are at it, remove the export too, since it should not be there. – Johan Myréen Aug 11 '21 at 13:48
  • 2
    @Nick, curious, that od output includes a comment that's not there in the cat output. – ilkkachu Aug 11 '21 at 19:32
  • @ilkkachu Thank you very much. Problem solved with your solution. I didn't include the comment from cat output at first, because I thought it was not helpful to solve the problem. It turns out that I was wrong. – Nick Aug 12 '21 at 01:24
  • @Nick, that's the thing, you always always always need to include things in full, because either the software stack is complex, the language quirky (everything to do with the shell), or something just buggy. At least with /etc/environment it looks like it works line-by-line, but esp. with code, seeing the whole file is important just so people can see that there's no surprises in the part left out. Except in the cases where that results in hundreds of lines which no-one wants to wade through. Finding the line there is one of the problems of debugging. – ilkkachu Aug 12 '21 at 07:30

1 Answers1

6
$ cat /etc/environment  
export NODE_OPTIONS="--max-old-space-size=5120"

So, /etc/environment is somewhat an odd case. It's read by the pam_env.so, and the man page for that says it should contain "simple KEY=VAL pairs on separate lines" but also some versions of the man page says that "The export instruction can be specified for bash compatibility, but will be ignored."

In any case, it's not read by a shell, and doesn't support all of the shell syntax. The man page mentions nothing about quotes and it doesn't support backslash escapes or expanding other variables, i.e. things like PATH=$PATH:/some/path or FOOPATH=$HOME/foo don't work.

But, that's not all, since it does seem to treat # signs as comment markers, even in the middle of a line, and at least on my Debian, it does remove quotes from the start and end of the value, if they exist, but without caring if they match.

E.g. with the two lines on the left, I get the two values on the right:

/etc/environment resulting variable
TEST1="hash#sign" TEST1=hash
TEST2="mixed quotes' TEST2=mixed quotes

Based on your od output, your /etc/environment actually contains this line:

export NODE_OPTIONS="--max-old-space-size=5120" #increase to 5gb

It gets cut on the hash sign, but because of the space after the ending quote, the quote isn't recognized or removed, and you get both the space and the quote in the value.

To go with what the manual says about "simple key=value pairs", you'd use:

# increase to 5 GB
NODE_OPTIONS=--max-old-space-size=5120

but based on the note about export and the observations above, this probably would also work:

# increase to 5 GB
export NODE_OPTIONS="--max-old-space-size=5120"

Just take care to clean up any trailing spaces, they may end up in the values or cause other issues.

Related:

ilkkachu
  • 138,973
  • IMO, this is an example of when The Robustness Principle: "be conservative in what you send, be liberal in what you accept" does not work. The reader of /etc/environment tries to adapt to shell syntax even if it doesn't support it, and does a lousy job at it. It would have been better if the text after the first = sign would have been taken as the value as is, including quotes and hash marks. This would have immediately made obvious where the error was instead of creating all this confusion. – Johan Myréen Aug 12 '21 at 07:29
  • 2
    @JohanMyréen, yes. It does make certain sense to support the shell syntax there, but that's somewhat annoying to do right, esp. since the shells vary in what quoting styles they support. The way it is now is a bit too broken, but probably can't be ever fixed since there are files in the wild with export and the quotes. On the plus side, it might be possible to persuade them to have the code remove trailing spaces before looking at the end quote, those are seldom actually needed anyway and it's already impossible to set arbitrary values via the file. – ilkkachu Aug 12 '21 at 07:42