4

I need to increment an environmental variable by these steps:

envar=1
export envar
sh script_incrementation
echo $envar

where script_incrementation contains something like this:

#! /bin/sh
envar=$[envar+1] #I've tried also other methods of incrementation
export envar

Whatever I do, after exiting the script the variable remains with its initial value 1.

THanks for your time.

2 Answers2

13

A shell script executes in its own shell, so you cannot affect the outer shell unless you source it. See this question for details of that discussion.

Consider the following script, which I will call Foo.sh.

#!/bin/bash

export HELLO=$(($HELLO+1))

Suppose in the outer shell, I define an environmental variable:

export HELLO=1

If I run the script like this, it run inside its own shell and will not affect the parent.

./Foo.sh

However, if I source it, it will just execute the commands in the current shell, and will achieve the desired affect.

. Foo.sh
echo $HELLO # prints 2
merlin2011
  • 71,677
  • 44
  • 195
  • 329
  • it works, thanks man, I can't believe I've spent an entire night wondering what could be wrong. –  Apr 28 '14 at 05:31
  • @SouthPole, You are welcome. Command line is fun but not always obvious. :) – merlin2011 Apr 28 '14 at 05:31
  • It should be`export HELLO=1`. Bash is case-sensitive, but can't edit only one sign. – h0ch5tr4355 Dec 10 '19 at 13:19
  • worth mentioning that `$(( expression ))` is an [arithmetic expansion](https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#Arithmetic-Expansion) that allows *the evaluation of an arithmetic expression and the substitution of the result*. – Wolfson Oct 15 '21 at 10:16
0

Your script can not change the environment of the calling process (shell), it merely inherits it.

So, if you export foo=bar, and then invoke sh (a new process) with your script, the script will see the value of $foo (which is "bar"), and it will be able to change its own copy of it – but that is not going to affect the environment of the parent process (where you exported the variable).

You can simply source your script in the original shell, i.e. run

source increment_script.sh

or

. increment_script.sh

and that will then change the value of the variable.

This is because sourceing a script avoids spawning a new shell (process).

Another trick is to have your script output the changed environment, and then eval that output, for example:

counter=$[counter+1]
echo "counter=$counter"

and then run that as

eval `increment_script.sh`
Sigi
  • 1,784
  • 13
  • 19