How do I set an environment variable on the command line and have it appear in commands?












130














If I run



export TEST=foo
echo $TEST


It outputs foo.



If I run



TEST=foo echo $TEST


It does not. How can I get this functionality without using export or a script?










share|improve this question
























  • Careful, there is more to this story than initially appears. I invite you to check my answer.
    – jasonleonhard
    Feb 7 '17 at 3:45


















130














If I run



export TEST=foo
echo $TEST


It outputs foo.



If I run



TEST=foo echo $TEST


It does not. How can I get this functionality without using export or a script?










share|improve this question
























  • Careful, there is more to this story than initially appears. I invite you to check my answer.
    – jasonleonhard
    Feb 7 '17 at 3:45
















130












130








130


28





If I run



export TEST=foo
echo $TEST


It outputs foo.



If I run



TEST=foo echo $TEST


It does not. How can I get this functionality without using export or a script?










share|improve this question















If I run



export TEST=foo
echo $TEST


It outputs foo.



If I run



TEST=foo echo $TEST


It does not. How can I get this functionality without using export or a script?







shell environment-variables echo






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 23 '12 at 23:35









Gilles

529k12810611587




529k12810611587










asked Nov 23 '12 at 10:17









ashleysmithgpu

99231017




99231017












  • Careful, there is more to this story than initially appears. I invite you to check my answer.
    – jasonleonhard
    Feb 7 '17 at 3:45




















  • Careful, there is more to this story than initially appears. I invite you to check my answer.
    – jasonleonhard
    Feb 7 '17 at 3:45


















Careful, there is more to this story than initially appears. I invite you to check my answer.
– jasonleonhard
Feb 7 '17 at 3:45






Careful, there is more to this story than initially appears. I invite you to check my answer.
– jasonleonhard
Feb 7 '17 at 3:45












4 Answers
4






active

oldest

votes


















148














This is because the shell expands the variable in the command line before it actually runs the command and at that time the variable doesn't exist. If you use



TEST=foo; echo $TEST


it will work.



export will make the variable appear in the environment of subsequently executed commands (for on how this works in bash see help export). If you only need the variable to appear in the environment of one command, use what you have tried, i.e.:



TEST=foo your-application





share|improve this answer



















  • 1




    What about /usr/bin/env? that doesn't work either, do you know why?
    – Benubird
    Jul 9 '14 at 16:43






  • 5




    The same reason - the shell expands the $TEST before the command line is executed. Once the echo is running (also note that echo will usually translate to the shell built-in command and not to /bin/echo) it sees the variable set in its environment. However, echo $TEST doesn't tell echo to output the contents of variable TEST from its environment. It tells the shell to run echo with argument being whatever currently is in the variable called TEST - and those are two very different things.
    – peterph
    Jul 9 '14 at 17:41










  • @peterph If shell expands the variable in the command line before it actually runs the command then why it doesn't expand it in var=value sh -c 'echo "$var"'?
    – haccks
    Mar 12 '18 at 21:56










  • As I explained to you here: it’s because variables are expanded inside double quotes (e.g., "… $var …") but not inside single quotes (e.g., '… $var …').  Since echo "$var" is inside single quotes, that entire string gets passed to the new (sh -c) shell without being interpreted by the outer, interactive shell. … (Cont’d)
    – G-Man
    Mar 14 '18 at 20:21










  • (Cont’d) …  As igal said yesterday, there are two rounds of parsing — although I believe that igal misread your question.  There are not two rounds of parsing apart from the parsing that is done by the parent shell.  There are two rounds of parsing — one done by the outer, interactive (parent) shell,  and one by the new (sh -c) child shell.
    – G-Man
    Mar 14 '18 at 20:21



















34














I suspect you want to have shell variables to have a limited scope, rather than environment variables. Environment variables are a list of strings passed to commands when they are executed.



In



var=value echo whatever


You're passing the var=value string to the environment that echo receives. However, echo doesn't do anything with its environment list and anyway in most shells, echo is built in and therefore not executed.



If you had written



var=value sh -c 'echo "$var"'


That would have been another matter. Here, we're passing var=value to the sh command, and sh does happen to use its environment. Shells convert each of the variables they receive from their environment to a shell variable, so the var environment variable sh receives will be converted to a $var variable, and when it expands it in that echo command line, that will become echo value. Because the environment is by default inherited, echo will also receive var=value in its environment (or would if it were executed), but again, echo doesn't care about the environment.



Now, if as I suspect, what you want is to limit the scope of shell variables, there are several possible approaches.



Portably (Bourne and POSIX):



(var=value; echo "1: $var"); echo "2: $var"


The (...) above starts a sub-shell (a new shell process in most shells), so any variable declared there will only affect that sub-shell, so I'd expect the code above to output "1: value" and "2: " or "2: whatever-var-was-set-to-before".



With most Bourne-like shells, you can use functions and the "local" builtin:



f() {
local var
var=value
echo "1: $var"
}
f
echo "2: $var"


With zsh, you can use inline functions:



(){ local var=value; echo "1: $var"; }; echo "2: $var"


or:



function { local var=value; echo "1: $var"; }; echo "2: $var"


With bash and zsh (but not ash, pdksh or AT&T ksh), this trick also works:



var=value eval 'echo "1: $var"'; echo "2: $var"


A variant that works in a few more shells (dash, mksh, yash) but not zsh (unless in sh/ksh emulation):



var=value command eval 'echo "1: $var"'; echo "2: $var"


(using command in front of a special builtin (here eval) in POSIX shells removes their specialness (here that variables assignments in from of them remain in effect after they have returned))






share|improve this answer























  • For my purposes, this is the correct solution. I don't want the variable 'var' to pollute the environment as it does in the accepted answer.
    – kronenpj
    Sep 13 '17 at 15:12



















5














You can get this working by using:



TEST=foo && echo $TEST





share|improve this answer

















  • 4




    In this case, TEST=foo is running as a separate statement - it is not just set in the context of echo.
    – codeforester
    Jan 3 '17 at 19:54



















1














You're doing it correctly, but the bash syntax is easy to misinterpret: you could think that echo $TEST causes echo to fetch TEST env var then print it, it does not. So given



export TEST=123


then



TEST=456 echo $TEST


involves the following sequence:





  1. The shell parses the whole command line and executes all variable substitutions, so the command line becomes



    TEST=456 echo 123



  2. It creates the temp vars set before the command, so it saves the current value of TEST and overwrites it with 456; the command line is now



    echo 123


  3. It executes the remaining command, which in this case prints 123 to stdout (so shell command that remains didn't even use the temp value of TEST)


  4. It restores the value of TEST



Use printenv instead, as it does not involve variable substitution:



>> export TEST=123
>> printenv TEST
123
>> TEST=456 printenv TEST
456
>> printenv TEST && TEST=456 printenv TEST && TEST=789 printenv TEST && printenv TEST
123
456
789
123
>>





share|improve this answer























  • printnenv helpful for proof of concept / testing
    – Daryn
    16 hours ago












  • @daryn If you meant printenv not printnenv can you please edit your comment (or delete it and re-enter it).
    – Oliver
    2 hours ago













Your Answer








StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "106"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f56444%2fhow-do-i-set-an-environment-variable-on-the-command-line-and-have-it-appear-in-c%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























4 Answers
4






active

oldest

votes








4 Answers
4






active

oldest

votes









active

oldest

votes






active

oldest

votes









148














This is because the shell expands the variable in the command line before it actually runs the command and at that time the variable doesn't exist. If you use



TEST=foo; echo $TEST


it will work.



export will make the variable appear in the environment of subsequently executed commands (for on how this works in bash see help export). If you only need the variable to appear in the environment of one command, use what you have tried, i.e.:



TEST=foo your-application





share|improve this answer



















  • 1




    What about /usr/bin/env? that doesn't work either, do you know why?
    – Benubird
    Jul 9 '14 at 16:43






  • 5




    The same reason - the shell expands the $TEST before the command line is executed. Once the echo is running (also note that echo will usually translate to the shell built-in command and not to /bin/echo) it sees the variable set in its environment. However, echo $TEST doesn't tell echo to output the contents of variable TEST from its environment. It tells the shell to run echo with argument being whatever currently is in the variable called TEST - and those are two very different things.
    – peterph
    Jul 9 '14 at 17:41










  • @peterph If shell expands the variable in the command line before it actually runs the command then why it doesn't expand it in var=value sh -c 'echo "$var"'?
    – haccks
    Mar 12 '18 at 21:56










  • As I explained to you here: it’s because variables are expanded inside double quotes (e.g., "… $var …") but not inside single quotes (e.g., '… $var …').  Since echo "$var" is inside single quotes, that entire string gets passed to the new (sh -c) shell without being interpreted by the outer, interactive shell. … (Cont’d)
    – G-Man
    Mar 14 '18 at 20:21










  • (Cont’d) …  As igal said yesterday, there are two rounds of parsing — although I believe that igal misread your question.  There are not two rounds of parsing apart from the parsing that is done by the parent shell.  There are two rounds of parsing — one done by the outer, interactive (parent) shell,  and one by the new (sh -c) child shell.
    – G-Man
    Mar 14 '18 at 20:21
















148














This is because the shell expands the variable in the command line before it actually runs the command and at that time the variable doesn't exist. If you use



TEST=foo; echo $TEST


it will work.



export will make the variable appear in the environment of subsequently executed commands (for on how this works in bash see help export). If you only need the variable to appear in the environment of one command, use what you have tried, i.e.:



TEST=foo your-application





share|improve this answer



















  • 1




    What about /usr/bin/env? that doesn't work either, do you know why?
    – Benubird
    Jul 9 '14 at 16:43






  • 5




    The same reason - the shell expands the $TEST before the command line is executed. Once the echo is running (also note that echo will usually translate to the shell built-in command and not to /bin/echo) it sees the variable set in its environment. However, echo $TEST doesn't tell echo to output the contents of variable TEST from its environment. It tells the shell to run echo with argument being whatever currently is in the variable called TEST - and those are two very different things.
    – peterph
    Jul 9 '14 at 17:41










  • @peterph If shell expands the variable in the command line before it actually runs the command then why it doesn't expand it in var=value sh -c 'echo "$var"'?
    – haccks
    Mar 12 '18 at 21:56










  • As I explained to you here: it’s because variables are expanded inside double quotes (e.g., "… $var …") but not inside single quotes (e.g., '… $var …').  Since echo "$var" is inside single quotes, that entire string gets passed to the new (sh -c) shell without being interpreted by the outer, interactive shell. … (Cont’d)
    – G-Man
    Mar 14 '18 at 20:21










  • (Cont’d) …  As igal said yesterday, there are two rounds of parsing — although I believe that igal misread your question.  There are not two rounds of parsing apart from the parsing that is done by the parent shell.  There are two rounds of parsing — one done by the outer, interactive (parent) shell,  and one by the new (sh -c) child shell.
    – G-Man
    Mar 14 '18 at 20:21














148












148








148






This is because the shell expands the variable in the command line before it actually runs the command and at that time the variable doesn't exist. If you use



TEST=foo; echo $TEST


it will work.



export will make the variable appear in the environment of subsequently executed commands (for on how this works in bash see help export). If you only need the variable to appear in the environment of one command, use what you have tried, i.e.:



TEST=foo your-application





share|improve this answer














This is because the shell expands the variable in the command line before it actually runs the command and at that time the variable doesn't exist. If you use



TEST=foo; echo $TEST


it will work.



export will make the variable appear in the environment of subsequently executed commands (for on how this works in bash see help export). If you only need the variable to appear in the environment of one command, use what you have tried, i.e.:



TEST=foo your-application






share|improve this answer














share|improve this answer



share|improve this answer








edited Oct 9 '14 at 12:20

























answered Nov 23 '12 at 10:37









peterph

23.3k24457




23.3k24457








  • 1




    What about /usr/bin/env? that doesn't work either, do you know why?
    – Benubird
    Jul 9 '14 at 16:43






  • 5




    The same reason - the shell expands the $TEST before the command line is executed. Once the echo is running (also note that echo will usually translate to the shell built-in command and not to /bin/echo) it sees the variable set in its environment. However, echo $TEST doesn't tell echo to output the contents of variable TEST from its environment. It tells the shell to run echo with argument being whatever currently is in the variable called TEST - and those are two very different things.
    – peterph
    Jul 9 '14 at 17:41










  • @peterph If shell expands the variable in the command line before it actually runs the command then why it doesn't expand it in var=value sh -c 'echo "$var"'?
    – haccks
    Mar 12 '18 at 21:56










  • As I explained to you here: it’s because variables are expanded inside double quotes (e.g., "… $var …") but not inside single quotes (e.g., '… $var …').  Since echo "$var" is inside single quotes, that entire string gets passed to the new (sh -c) shell without being interpreted by the outer, interactive shell. … (Cont’d)
    – G-Man
    Mar 14 '18 at 20:21










  • (Cont’d) …  As igal said yesterday, there are two rounds of parsing — although I believe that igal misread your question.  There are not two rounds of parsing apart from the parsing that is done by the parent shell.  There are two rounds of parsing — one done by the outer, interactive (parent) shell,  and one by the new (sh -c) child shell.
    – G-Man
    Mar 14 '18 at 20:21














  • 1




    What about /usr/bin/env? that doesn't work either, do you know why?
    – Benubird
    Jul 9 '14 at 16:43






  • 5




    The same reason - the shell expands the $TEST before the command line is executed. Once the echo is running (also note that echo will usually translate to the shell built-in command and not to /bin/echo) it sees the variable set in its environment. However, echo $TEST doesn't tell echo to output the contents of variable TEST from its environment. It tells the shell to run echo with argument being whatever currently is in the variable called TEST - and those are two very different things.
    – peterph
    Jul 9 '14 at 17:41










  • @peterph If shell expands the variable in the command line before it actually runs the command then why it doesn't expand it in var=value sh -c 'echo "$var"'?
    – haccks
    Mar 12 '18 at 21:56










  • As I explained to you here: it’s because variables are expanded inside double quotes (e.g., "… $var …") but not inside single quotes (e.g., '… $var …').  Since echo "$var" is inside single quotes, that entire string gets passed to the new (sh -c) shell without being interpreted by the outer, interactive shell. … (Cont’d)
    – G-Man
    Mar 14 '18 at 20:21










  • (Cont’d) …  As igal said yesterday, there are two rounds of parsing — although I believe that igal misread your question.  There are not two rounds of parsing apart from the parsing that is done by the parent shell.  There are two rounds of parsing — one done by the outer, interactive (parent) shell,  and one by the new (sh -c) child shell.
    – G-Man
    Mar 14 '18 at 20:21








1




1




What about /usr/bin/env? that doesn't work either, do you know why?
– Benubird
Jul 9 '14 at 16:43




What about /usr/bin/env? that doesn't work either, do you know why?
– Benubird
Jul 9 '14 at 16:43




5




5




The same reason - the shell expands the $TEST before the command line is executed. Once the echo is running (also note that echo will usually translate to the shell built-in command and not to /bin/echo) it sees the variable set in its environment. However, echo $TEST doesn't tell echo to output the contents of variable TEST from its environment. It tells the shell to run echo with argument being whatever currently is in the variable called TEST - and those are two very different things.
– peterph
Jul 9 '14 at 17:41




The same reason - the shell expands the $TEST before the command line is executed. Once the echo is running (also note that echo will usually translate to the shell built-in command and not to /bin/echo) it sees the variable set in its environment. However, echo $TEST doesn't tell echo to output the contents of variable TEST from its environment. It tells the shell to run echo with argument being whatever currently is in the variable called TEST - and those are two very different things.
– peterph
Jul 9 '14 at 17:41












@peterph If shell expands the variable in the command line before it actually runs the command then why it doesn't expand it in var=value sh -c 'echo "$var"'?
– haccks
Mar 12 '18 at 21:56




@peterph If shell expands the variable in the command line before it actually runs the command then why it doesn't expand it in var=value sh -c 'echo "$var"'?
– haccks
Mar 12 '18 at 21:56












As I explained to you here: it’s because variables are expanded inside double quotes (e.g., "… $var …") but not inside single quotes (e.g., '… $var …').  Since echo "$var" is inside single quotes, that entire string gets passed to the new (sh -c) shell without being interpreted by the outer, interactive shell. … (Cont’d)
– G-Man
Mar 14 '18 at 20:21




As I explained to you here: it’s because variables are expanded inside double quotes (e.g., "… $var …") but not inside single quotes (e.g., '… $var …').  Since echo "$var" is inside single quotes, that entire string gets passed to the new (sh -c) shell without being interpreted by the outer, interactive shell. … (Cont’d)
– G-Man
Mar 14 '18 at 20:21












(Cont’d) …  As igal said yesterday, there are two rounds of parsing — although I believe that igal misread your question.  There are not two rounds of parsing apart from the parsing that is done by the parent shell.  There are two rounds of parsing — one done by the outer, interactive (parent) shell,  and one by the new (sh -c) child shell.
– G-Man
Mar 14 '18 at 20:21




(Cont’d) …  As igal said yesterday, there are two rounds of parsing — although I believe that igal misread your question.  There are not two rounds of parsing apart from the parsing that is done by the parent shell.  There are two rounds of parsing — one done by the outer, interactive (parent) shell,  and one by the new (sh -c) child shell.
– G-Man
Mar 14 '18 at 20:21













34














I suspect you want to have shell variables to have a limited scope, rather than environment variables. Environment variables are a list of strings passed to commands when they are executed.



In



var=value echo whatever


You're passing the var=value string to the environment that echo receives. However, echo doesn't do anything with its environment list and anyway in most shells, echo is built in and therefore not executed.



If you had written



var=value sh -c 'echo "$var"'


That would have been another matter. Here, we're passing var=value to the sh command, and sh does happen to use its environment. Shells convert each of the variables they receive from their environment to a shell variable, so the var environment variable sh receives will be converted to a $var variable, and when it expands it in that echo command line, that will become echo value. Because the environment is by default inherited, echo will also receive var=value in its environment (or would if it were executed), but again, echo doesn't care about the environment.



Now, if as I suspect, what you want is to limit the scope of shell variables, there are several possible approaches.



Portably (Bourne and POSIX):



(var=value; echo "1: $var"); echo "2: $var"


The (...) above starts a sub-shell (a new shell process in most shells), so any variable declared there will only affect that sub-shell, so I'd expect the code above to output "1: value" and "2: " or "2: whatever-var-was-set-to-before".



With most Bourne-like shells, you can use functions and the "local" builtin:



f() {
local var
var=value
echo "1: $var"
}
f
echo "2: $var"


With zsh, you can use inline functions:



(){ local var=value; echo "1: $var"; }; echo "2: $var"


or:



function { local var=value; echo "1: $var"; }; echo "2: $var"


With bash and zsh (but not ash, pdksh or AT&T ksh), this trick also works:



var=value eval 'echo "1: $var"'; echo "2: $var"


A variant that works in a few more shells (dash, mksh, yash) but not zsh (unless in sh/ksh emulation):



var=value command eval 'echo "1: $var"'; echo "2: $var"


(using command in front of a special builtin (here eval) in POSIX shells removes their specialness (here that variables assignments in from of them remain in effect after they have returned))






share|improve this answer























  • For my purposes, this is the correct solution. I don't want the variable 'var' to pollute the environment as it does in the accepted answer.
    – kronenpj
    Sep 13 '17 at 15:12
















34














I suspect you want to have shell variables to have a limited scope, rather than environment variables. Environment variables are a list of strings passed to commands when they are executed.



In



var=value echo whatever


You're passing the var=value string to the environment that echo receives. However, echo doesn't do anything with its environment list and anyway in most shells, echo is built in and therefore not executed.



If you had written



var=value sh -c 'echo "$var"'


That would have been another matter. Here, we're passing var=value to the sh command, and sh does happen to use its environment. Shells convert each of the variables they receive from their environment to a shell variable, so the var environment variable sh receives will be converted to a $var variable, and when it expands it in that echo command line, that will become echo value. Because the environment is by default inherited, echo will also receive var=value in its environment (or would if it were executed), but again, echo doesn't care about the environment.



Now, if as I suspect, what you want is to limit the scope of shell variables, there are several possible approaches.



Portably (Bourne and POSIX):



(var=value; echo "1: $var"); echo "2: $var"


The (...) above starts a sub-shell (a new shell process in most shells), so any variable declared there will only affect that sub-shell, so I'd expect the code above to output "1: value" and "2: " or "2: whatever-var-was-set-to-before".



With most Bourne-like shells, you can use functions and the "local" builtin:



f() {
local var
var=value
echo "1: $var"
}
f
echo "2: $var"


With zsh, you can use inline functions:



(){ local var=value; echo "1: $var"; }; echo "2: $var"


or:



function { local var=value; echo "1: $var"; }; echo "2: $var"


With bash and zsh (but not ash, pdksh or AT&T ksh), this trick also works:



var=value eval 'echo "1: $var"'; echo "2: $var"


A variant that works in a few more shells (dash, mksh, yash) but not zsh (unless in sh/ksh emulation):



var=value command eval 'echo "1: $var"'; echo "2: $var"


(using command in front of a special builtin (here eval) in POSIX shells removes their specialness (here that variables assignments in from of them remain in effect after they have returned))






share|improve this answer























  • For my purposes, this is the correct solution. I don't want the variable 'var' to pollute the environment as it does in the accepted answer.
    – kronenpj
    Sep 13 '17 at 15:12














34












34








34






I suspect you want to have shell variables to have a limited scope, rather than environment variables. Environment variables are a list of strings passed to commands when they are executed.



In



var=value echo whatever


You're passing the var=value string to the environment that echo receives. However, echo doesn't do anything with its environment list and anyway in most shells, echo is built in and therefore not executed.



If you had written



var=value sh -c 'echo "$var"'


That would have been another matter. Here, we're passing var=value to the sh command, and sh does happen to use its environment. Shells convert each of the variables they receive from their environment to a shell variable, so the var environment variable sh receives will be converted to a $var variable, and when it expands it in that echo command line, that will become echo value. Because the environment is by default inherited, echo will also receive var=value in its environment (or would if it were executed), but again, echo doesn't care about the environment.



Now, if as I suspect, what you want is to limit the scope of shell variables, there are several possible approaches.



Portably (Bourne and POSIX):



(var=value; echo "1: $var"); echo "2: $var"


The (...) above starts a sub-shell (a new shell process in most shells), so any variable declared there will only affect that sub-shell, so I'd expect the code above to output "1: value" and "2: " or "2: whatever-var-was-set-to-before".



With most Bourne-like shells, you can use functions and the "local" builtin:



f() {
local var
var=value
echo "1: $var"
}
f
echo "2: $var"


With zsh, you can use inline functions:



(){ local var=value; echo "1: $var"; }; echo "2: $var"


or:



function { local var=value; echo "1: $var"; }; echo "2: $var"


With bash and zsh (but not ash, pdksh or AT&T ksh), this trick also works:



var=value eval 'echo "1: $var"'; echo "2: $var"


A variant that works in a few more shells (dash, mksh, yash) but not zsh (unless in sh/ksh emulation):



var=value command eval 'echo "1: $var"'; echo "2: $var"


(using command in front of a special builtin (here eval) in POSIX shells removes their specialness (here that variables assignments in from of them remain in effect after they have returned))






share|improve this answer














I suspect you want to have shell variables to have a limited scope, rather than environment variables. Environment variables are a list of strings passed to commands when they are executed.



In



var=value echo whatever


You're passing the var=value string to the environment that echo receives. However, echo doesn't do anything with its environment list and anyway in most shells, echo is built in and therefore not executed.



If you had written



var=value sh -c 'echo "$var"'


That would have been another matter. Here, we're passing var=value to the sh command, and sh does happen to use its environment. Shells convert each of the variables they receive from their environment to a shell variable, so the var environment variable sh receives will be converted to a $var variable, and when it expands it in that echo command line, that will become echo value. Because the environment is by default inherited, echo will also receive var=value in its environment (or would if it were executed), but again, echo doesn't care about the environment.



Now, if as I suspect, what you want is to limit the scope of shell variables, there are several possible approaches.



Portably (Bourne and POSIX):



(var=value; echo "1: $var"); echo "2: $var"


The (...) above starts a sub-shell (a new shell process in most shells), so any variable declared there will only affect that sub-shell, so I'd expect the code above to output "1: value" and "2: " or "2: whatever-var-was-set-to-before".



With most Bourne-like shells, you can use functions and the "local" builtin:



f() {
local var
var=value
echo "1: $var"
}
f
echo "2: $var"


With zsh, you can use inline functions:



(){ local var=value; echo "1: $var"; }; echo "2: $var"


or:



function { local var=value; echo "1: $var"; }; echo "2: $var"


With bash and zsh (but not ash, pdksh or AT&T ksh), this trick also works:



var=value eval 'echo "1: $var"'; echo "2: $var"


A variant that works in a few more shells (dash, mksh, yash) but not zsh (unless in sh/ksh emulation):



var=value command eval 'echo "1: $var"'; echo "2: $var"


(using command in front of a special builtin (here eval) in POSIX shells removes their specialness (here that variables assignments in from of them remain in effect after they have returned))







share|improve this answer














share|improve this answer



share|improve this answer








edited Dec 2 '16 at 10:34

























answered Nov 23 '12 at 11:31









Stéphane Chazelas

300k54564913




300k54564913












  • For my purposes, this is the correct solution. I don't want the variable 'var' to pollute the environment as it does in the accepted answer.
    – kronenpj
    Sep 13 '17 at 15:12


















  • For my purposes, this is the correct solution. I don't want the variable 'var' to pollute the environment as it does in the accepted answer.
    – kronenpj
    Sep 13 '17 at 15:12
















For my purposes, this is the correct solution. I don't want the variable 'var' to pollute the environment as it does in the accepted answer.
– kronenpj
Sep 13 '17 at 15:12




For my purposes, this is the correct solution. I don't want the variable 'var' to pollute the environment as it does in the accepted answer.
– kronenpj
Sep 13 '17 at 15:12











5














You can get this working by using:



TEST=foo && echo $TEST





share|improve this answer

















  • 4




    In this case, TEST=foo is running as a separate statement - it is not just set in the context of echo.
    – codeforester
    Jan 3 '17 at 19:54
















5














You can get this working by using:



TEST=foo && echo $TEST





share|improve this answer

















  • 4




    In this case, TEST=foo is running as a separate statement - it is not just set in the context of echo.
    – codeforester
    Jan 3 '17 at 19:54














5












5








5






You can get this working by using:



TEST=foo && echo $TEST





share|improve this answer












You can get this working by using:



TEST=foo && echo $TEST






share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 23 '12 at 10:23









pradeepchhetri

6,26093356




6,26093356








  • 4




    In this case, TEST=foo is running as a separate statement - it is not just set in the context of echo.
    – codeforester
    Jan 3 '17 at 19:54














  • 4




    In this case, TEST=foo is running as a separate statement - it is not just set in the context of echo.
    – codeforester
    Jan 3 '17 at 19:54








4




4




In this case, TEST=foo is running as a separate statement - it is not just set in the context of echo.
– codeforester
Jan 3 '17 at 19:54




In this case, TEST=foo is running as a separate statement - it is not just set in the context of echo.
– codeforester
Jan 3 '17 at 19:54











1














You're doing it correctly, but the bash syntax is easy to misinterpret: you could think that echo $TEST causes echo to fetch TEST env var then print it, it does not. So given



export TEST=123


then



TEST=456 echo $TEST


involves the following sequence:





  1. The shell parses the whole command line and executes all variable substitutions, so the command line becomes



    TEST=456 echo 123



  2. It creates the temp vars set before the command, so it saves the current value of TEST and overwrites it with 456; the command line is now



    echo 123


  3. It executes the remaining command, which in this case prints 123 to stdout (so shell command that remains didn't even use the temp value of TEST)


  4. It restores the value of TEST



Use printenv instead, as it does not involve variable substitution:



>> export TEST=123
>> printenv TEST
123
>> TEST=456 printenv TEST
456
>> printenv TEST && TEST=456 printenv TEST && TEST=789 printenv TEST && printenv TEST
123
456
789
123
>>





share|improve this answer























  • printnenv helpful for proof of concept / testing
    – Daryn
    16 hours ago












  • @daryn If you meant printenv not printnenv can you please edit your comment (or delete it and re-enter it).
    – Oliver
    2 hours ago


















1














You're doing it correctly, but the bash syntax is easy to misinterpret: you could think that echo $TEST causes echo to fetch TEST env var then print it, it does not. So given



export TEST=123


then



TEST=456 echo $TEST


involves the following sequence:





  1. The shell parses the whole command line and executes all variable substitutions, so the command line becomes



    TEST=456 echo 123



  2. It creates the temp vars set before the command, so it saves the current value of TEST and overwrites it with 456; the command line is now



    echo 123


  3. It executes the remaining command, which in this case prints 123 to stdout (so shell command that remains didn't even use the temp value of TEST)


  4. It restores the value of TEST



Use printenv instead, as it does not involve variable substitution:



>> export TEST=123
>> printenv TEST
123
>> TEST=456 printenv TEST
456
>> printenv TEST && TEST=456 printenv TEST && TEST=789 printenv TEST && printenv TEST
123
456
789
123
>>





share|improve this answer























  • printnenv helpful for proof of concept / testing
    – Daryn
    16 hours ago












  • @daryn If you meant printenv not printnenv can you please edit your comment (or delete it and re-enter it).
    – Oliver
    2 hours ago
















1












1








1






You're doing it correctly, but the bash syntax is easy to misinterpret: you could think that echo $TEST causes echo to fetch TEST env var then print it, it does not. So given



export TEST=123


then



TEST=456 echo $TEST


involves the following sequence:





  1. The shell parses the whole command line and executes all variable substitutions, so the command line becomes



    TEST=456 echo 123



  2. It creates the temp vars set before the command, so it saves the current value of TEST and overwrites it with 456; the command line is now



    echo 123


  3. It executes the remaining command, which in this case prints 123 to stdout (so shell command that remains didn't even use the temp value of TEST)


  4. It restores the value of TEST



Use printenv instead, as it does not involve variable substitution:



>> export TEST=123
>> printenv TEST
123
>> TEST=456 printenv TEST
456
>> printenv TEST && TEST=456 printenv TEST && TEST=789 printenv TEST && printenv TEST
123
456
789
123
>>





share|improve this answer














You're doing it correctly, but the bash syntax is easy to misinterpret: you could think that echo $TEST causes echo to fetch TEST env var then print it, it does not. So given



export TEST=123


then



TEST=456 echo $TEST


involves the following sequence:





  1. The shell parses the whole command line and executes all variable substitutions, so the command line becomes



    TEST=456 echo 123



  2. It creates the temp vars set before the command, so it saves the current value of TEST and overwrites it with 456; the command line is now



    echo 123


  3. It executes the remaining command, which in this case prints 123 to stdout (so shell command that remains didn't even use the temp value of TEST)


  4. It restores the value of TEST



Use printenv instead, as it does not involve variable substitution:



>> export TEST=123
>> printenv TEST
123
>> TEST=456 printenv TEST
456
>> printenv TEST && TEST=456 printenv TEST && TEST=789 printenv TEST && printenv TEST
123
456
789
123
>>






share|improve this answer














share|improve this answer



share|improve this answer








edited 2 hours ago

























answered Apr 5 '18 at 0:13









Oliver

1214




1214












  • printnenv helpful for proof of concept / testing
    – Daryn
    16 hours ago












  • @daryn If you meant printenv not printnenv can you please edit your comment (or delete it and re-enter it).
    – Oliver
    2 hours ago




















  • printnenv helpful for proof of concept / testing
    – Daryn
    16 hours ago












  • @daryn If you meant printenv not printnenv can you please edit your comment (or delete it and re-enter it).
    – Oliver
    2 hours ago


















printnenv helpful for proof of concept / testing
– Daryn
16 hours ago






printnenv helpful for proof of concept / testing
– Daryn
16 hours ago














@daryn If you meant printenv not printnenv can you please edit your comment (or delete it and re-enter it).
– Oliver
2 hours ago






@daryn If you meant printenv not printnenv can you please edit your comment (or delete it and re-enter it).
– Oliver
2 hours ago




















draft saved

draft discarded




















































Thanks for contributing an answer to Unix & Linux Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f56444%2fhow-do-i-set-an-environment-variable-on-the-command-line-and-have-it-appear-in-c%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

宮崎県

濃尾地震

シテ島