Take the 2-minute tour ×
src="binds.c engine.c console.c"
echo $src
gcc $src

The batch file above works with the echo but the gcc fails. If I type gcc $src at the command line, that works. So it seems that gcc doesn't get environment local variables within a batch file?


share|improve this question
Did you export the variable? –  Marc B Jan 29 '12 at 19:11
Doesn't work saying what? –  Michael Krelin - hacker Jan 29 '12 at 19:11
export? It's in the same script, for what I can tell by the question. –  Michael Krelin - hacker Jan 29 '12 at 19:11
What's the output of the "batch file" when you run it? –  rob mayoff Jan 29 '12 at 19:13
This is not a batch file. This is a shell script. –  cha0site Jan 29 '12 at 19:18
show 1 more comment

1 Answer

If you're using Cygwin, then you're running on Windows in a Unix-emulation. A pretty good one, but still an emulation. However, you are also probably using bash as your shell, which is good (and if by any chance you're using Korn shell, what I say below applies equally, and if you're using /bin/sh, that is effectively a subset of bash and what I say applies to that, too).

Note that you can define variables in your shell that are not in the shell's environment. This distinction is important when it comes to running other scripts.

src="binds.c engine.c console.c"

This creates a non-environment variable called src. You can now use this at the command line:

echo $src
gcc -c $src

The echo command will list the three names, and GCC will be run and will attempt to compile all three source files. However, if you run the env command, you will not see src in the environment. On the other hand, if you run the set command, you will see src.

env    # No arguments - list the environment variables that are exported
set    # No arguments - lists variables, exported and non-exported

Now suppose that you have (or create) a script called compile in the current directory that contains:

gcc -c $src

The script should be executable (chmod +x compile). If you run:


the script does not see the variable $src because it is not exported, so you get an error about no file names specified from GCC. Funnily enough, if you run either of these:

. ./compile
source ./compile

then the compilation occurs as you wanted. That's because instead of starting a sub-shell to execute the script, the current shell reads the script, and the variable src is defined.

If you now export src, it becomes available to sub-shells and other programs:

export src     # Sufficient given the initial assignment
export src="binds.c engine.c console.c" # Set and export; not portable to Bourne shell

Now if you run env, you will see src listed. And now if you run ./compile, it will have a variable src in its environment, so the compilation will occur as expected.

So, the key points are:

  • Not all shell variables are environment variables.
  • To make a variable into an environment variable, you must export it explicitly.

There are some other tricks that can be pulled with environment variables, but they are not yet germane to your situation and would more likely confuse than help. (I'm thinking of set -k and var=value cmd arg1 ... for those who know.)

share|improve this answer
Wow, a shell problem, I am running cygwin in windows. Thanks a bunch, you have cleared a mystery. –  Matt Young Jan 30 '12 at 20:47
add comment

Your Answer


