How to assign and reference environment variables containing square brackets in PowershellWhat type of object is $<drivename>: (such as `$code:`) in Powershell?Setting environment variables on OS XHow do I iterate over a range of numbers defined by variables in Bash?How to concatenate string variables in BashRead environment variables in Node.jsHow to access environment variable values?List all environment variables from command line?How do I delete an exported environment variable?How do you comment out code in PowerShell?Setting an environment variable before a command in bash not working for second command in a pipeHow do I pass environment variables to Docker containers?
What does "another" mean in this case?
How frequently do Russian people still refer to others by their patronymic (отчество)?
Should I cheat if the majority does it?
My mother co-signed for my car. Can she take it away from me if I am the one making car payments?
What is meaning of 4 letter acronyms in Roman names like Titus Flavius T. f. T. n. Sabinus?
How is /a/ pronounced before n/m in French?
Are there advantages in writing by hand over typing out a story?
What is a "tittering order"?
What is the right way to query an I2C device from an interrupt service routine?
Show that there are infinitely more problems than we will ever be able to compute
What is the difference between case and adpositions?
Is my background sufficient to start Quantum Computing
How can I know (without going to the station) if RATP is offering the Anti Pollution tickets?
Is it advisable to inform the CEO about his brother accessing his office?
Can the word "coexist" be used for more than two things/people/subjects/... etc?
Will greasing clutch parts make it softer
Can you use a reaction to affect initiative rolls?
How to widen the page
Solving Equations with HeavisideTheta Functions
Which are more efficient in putting out wildfires: planes or helicopters?
Isn't "Dave's protocol" good if only the database, and not the code, is leaked?
Who are the police in Hong Kong?
Has there ever been a cold war other than between the U.S. and the U.S.S.R.?
Did Snape really give Umbridge a fake Veritaserum potion that Harry later pretended to drink?
How to assign and reference environment variables containing square brackets in Powershell
What type of object is $<drivename>: (such as `$code:`) in Powershell?Setting environment variables on OS XHow do I iterate over a range of numbers defined by variables in Bash?How to concatenate string variables in BashRead environment variables in Node.jsHow to access environment variable values?List all environment variables from command line?How do I delete an exported environment variable?How do you comment out code in PowerShell?Setting an environment variable before a command in bash not working for second command in a pipeHow do I pass environment variables to Docker containers?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
When the PSDrive is not specified, the following works:
$[foo]="bar"
echo $[foo]
But the following does not work
$env:$[foo]="bar"
At line:1 char:1
+ $env:$[foo]="bar"
+ ~~~~~
Variable reference is not valid. ':' was not followed by a valid variable name character. Consider using $ to delimit the name.
At line:1 char:6
+ $env:$[foo]="bar"
+ ~~~~~~~~~~~~~~
Unexpected token '$[foo]="bar"' in expression or statement.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : InvalidVariableReferenceWithDrive
$env:[foo]="bar"
Cannot find path 'env:[foo]' because it does not exist.
At line:1 char:1
+ $env:[foo]="bar"
+ ~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (env:[foo]:String) [], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound
The following works, though I am curious if there's short hand syntax for it:
Set-Item -LiteralPath env:$[foo] -Value "bar"
Get-Item -LiteralPath env:$[foo] | % $_.Value
However the following does not work:
Set-Item -LiteralPath env:$[foo]2 -Value "bar"
Set-Item : Cannot process argument because the value of argument "name" is null. Change the value of argument "name" to a non-null value.
At line:1 char:1
+ Set-Item -LiteralPath env:$[foo]2 -Value "bar"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:String) [Set-Item], PSArgumentNullException
+ FullyQualifiedErrorId : SetItemNullName,Microsoft.PowerShell.Commands.SetItemCommand
powershell syntax namespaces environment-variables
add a comment |
When the PSDrive is not specified, the following works:
$[foo]="bar"
echo $[foo]
But the following does not work
$env:$[foo]="bar"
At line:1 char:1
+ $env:$[foo]="bar"
+ ~~~~~
Variable reference is not valid. ':' was not followed by a valid variable name character. Consider using $ to delimit the name.
At line:1 char:6
+ $env:$[foo]="bar"
+ ~~~~~~~~~~~~~~
Unexpected token '$[foo]="bar"' in expression or statement.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : InvalidVariableReferenceWithDrive
$env:[foo]="bar"
Cannot find path 'env:[foo]' because it does not exist.
At line:1 char:1
+ $env:[foo]="bar"
+ ~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (env:[foo]:String) [], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound
The following works, though I am curious if there's short hand syntax for it:
Set-Item -LiteralPath env:$[foo] -Value "bar"
Get-Item -LiteralPath env:$[foo] | % $_.Value
However the following does not work:
Set-Item -LiteralPath env:$[foo]2 -Value "bar"
Set-Item : Cannot process argument because the value of argument "name" is null. Change the value of argument "name" to a non-null value.
At line:1 char:1
+ Set-Item -LiteralPath env:$[foo]2 -Value "bar"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:String) [Set-Item], PSArgumentNullException
+ FullyQualifiedErrorId : SetItemNullName,Microsoft.PowerShell.Commands.SetItemCommand
powershell syntax namespaces environment-variables
Great question; as an aside:Get-Item -LiteralPath env:$[foo]andSet-Item -LiteralPath env:$[foo] -Value "bar"do not work either, or at least won't work they way you expect, due to up-front string expansion.
– mklement0
Mar 25 at 19:50
add a comment |
When the PSDrive is not specified, the following works:
$[foo]="bar"
echo $[foo]
But the following does not work
$env:$[foo]="bar"
At line:1 char:1
+ $env:$[foo]="bar"
+ ~~~~~
Variable reference is not valid. ':' was not followed by a valid variable name character. Consider using $ to delimit the name.
At line:1 char:6
+ $env:$[foo]="bar"
+ ~~~~~~~~~~~~~~
Unexpected token '$[foo]="bar"' in expression or statement.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : InvalidVariableReferenceWithDrive
$env:[foo]="bar"
Cannot find path 'env:[foo]' because it does not exist.
At line:1 char:1
+ $env:[foo]="bar"
+ ~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (env:[foo]:String) [], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound
The following works, though I am curious if there's short hand syntax for it:
Set-Item -LiteralPath env:$[foo] -Value "bar"
Get-Item -LiteralPath env:$[foo] | % $_.Value
However the following does not work:
Set-Item -LiteralPath env:$[foo]2 -Value "bar"
Set-Item : Cannot process argument because the value of argument "name" is null. Change the value of argument "name" to a non-null value.
At line:1 char:1
+ Set-Item -LiteralPath env:$[foo]2 -Value "bar"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:String) [Set-Item], PSArgumentNullException
+ FullyQualifiedErrorId : SetItemNullName,Microsoft.PowerShell.Commands.SetItemCommand
powershell syntax namespaces environment-variables
When the PSDrive is not specified, the following works:
$[foo]="bar"
echo $[foo]
But the following does not work
$env:$[foo]="bar"
At line:1 char:1
+ $env:$[foo]="bar"
+ ~~~~~
Variable reference is not valid. ':' was not followed by a valid variable name character. Consider using $ to delimit the name.
At line:1 char:6
+ $env:$[foo]="bar"
+ ~~~~~~~~~~~~~~
Unexpected token '$[foo]="bar"' in expression or statement.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : InvalidVariableReferenceWithDrive
$env:[foo]="bar"
Cannot find path 'env:[foo]' because it does not exist.
At line:1 char:1
+ $env:[foo]="bar"
+ ~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (env:[foo]:String) [], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound
The following works, though I am curious if there's short hand syntax for it:
Set-Item -LiteralPath env:$[foo] -Value "bar"
Get-Item -LiteralPath env:$[foo] | % $_.Value
However the following does not work:
Set-Item -LiteralPath env:$[foo]2 -Value "bar"
Set-Item : Cannot process argument because the value of argument "name" is null. Change the value of argument "name" to a non-null value.
At line:1 char:1
+ Set-Item -LiteralPath env:$[foo]2 -Value "bar"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:String) [Set-Item], PSArgumentNullException
+ FullyQualifiedErrorId : SetItemNullName,Microsoft.PowerShell.Commands.SetItemCommand
powershell syntax namespaces environment-variables
powershell syntax namespaces environment-variables
edited Mar 25 at 19:56
mklement0
148k24 gold badges269 silver badges303 bronze badges
148k24 gold badges269 silver badges303 bronze badges
asked Mar 25 at 17:52
cdmihaicdmihai
1,8102 gold badges15 silver badges14 bronze badges
1,8102 gold badges15 silver badges14 bronze badges
Great question; as an aside:Get-Item -LiteralPath env:$[foo]andSet-Item -LiteralPath env:$[foo] -Value "bar"do not work either, or at least won't work they way you expect, due to up-front string expansion.
– mklement0
Mar 25 at 19:50
add a comment |
Great question; as an aside:Get-Item -LiteralPath env:$[foo]andSet-Item -LiteralPath env:$[foo] -Value "bar"do not work either, or at least won't work they way you expect, due to up-front string expansion.
– mklement0
Mar 25 at 19:50
Great question; as an aside:
Get-Item -LiteralPath env:$[foo] and Set-Item -LiteralPath env:$[foo] -Value "bar" do not work either, or at least won't work they way you expect, due to up-front string expansion.– mklement0
Mar 25 at 19:50
Great question; as an aside:
Get-Item -LiteralPath env:$[foo] and Set-Item -LiteralPath env:$[foo] -Value "bar" do not work either, or at least won't work they way you expect, due to up-front string expansion.– mklement0
Mar 25 at 19:50
add a comment |
1 Answer
1
active
oldest
votes
Written as of PowerShell Core 6.2.0
The reason is that PowerShell treats the following:
$<drive>:<name>
as if you had specified:
Get-Content -Path <drive>:<name> # or, with assignment, Set-Content -Path ...
This notation - though often used with the Env: drive (e.g., $env:Path) - is little-known as a general paradigm named namespace variable notation, which is explained in this answer.
The problem is the use of -Path rather than -LiteralPath, because -Path interprets its argument as a wildcard expression.
Therefore, the [foo] in $env:[foo] - rather than being used as-is - is interpreted as a wildcard expression that matches a single character that is either f or o ([foo] is a character set or range ([...]) that matches any one of the (distinct) characters inside - see about_Wildcards).
On assigning to $env:[foo], the logic of Set-Content -Path requires that a wildcard-based path resolve to something existing, even though you're generally not required to explicitly create environment variables; e.g., $env:NoSuchVarExistsYet = 'new' works just fine.
Workaround:
Use double(!)-`-escaping of the wildcard metacharacters:
# Namespace variable notation only works with if you
# double(!)-backtick-escape the wildcard metacharacters:
# Assign to / implicitly create env. var '[foo]'
$env:``[foo``] = 'bar'
# Get its value.
$env:``[foo``]
Note:
Escaping shouldn't be required at all, because there is no good reason to treat paths that conceptually identify a given, known item as wildcard expressions - see this GitHub issue.
That double
`-escaping is needed is an added quirk - see this GitHub issue.Another workaround - one that doesn't involve escaping - is to use
Set-Content -LiteralPath env:[foo] barandGet-Content -LiteralPath env:[foo], but that is both verbose and slow.
As for the other syntax variations you tried:
$env:$[foo]="bar"
Since your variable reference isn't ...-enclosed as a whole (except for the initial $), the token that follows the : is only allowed to contain characters that do not require escaping - and $, and all violate that rule.
...-enclosing the entire path -$env:[foo]- solves the syntax problem, but runs into the problem detailed above.
Set-Item -LiteralPath env:$[foo] -Value "bar"
This does not work in general, because string expansion is applied beforehand here - it is as if you had passed "env:$[foo]": the reference to a (regular) variable named $[foo] is expanded (replaced with its value) and in effect appended to literal env:, before handing the result to Set-Item.
If such a regular variable doesn't exist, what Set-Item sees is just env: (because non-existent variables default to $null, which becomes the empty string in a string context), which causes an error due to the lack of variable name.
By contrast, the following would set an environment variable named unrelated instead:
# Create a regular variable literally named '[foo]'.
$[foo] = 'unrelated'
# !! The following sets env:unrelated, i.e., env. var 'unrelated',
# !! due to the string expansion that is performed on the -LiteralPath
# !! argument up front.
Set-Item -LiteralPath env:$[foo] bar
$env:unrelated # -> 'bar'
The same applies to Get-Item -LiteralPath env:$[foo] and Set-Item -LiteralPath env:$[foo]2 -Value "bar".
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
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: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
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
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55343828%2fhow-to-assign-and-reference-environment-variables-containing-square-brackets-in%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Written as of PowerShell Core 6.2.0
The reason is that PowerShell treats the following:
$<drive>:<name>
as if you had specified:
Get-Content -Path <drive>:<name> # or, with assignment, Set-Content -Path ...
This notation - though often used with the Env: drive (e.g., $env:Path) - is little-known as a general paradigm named namespace variable notation, which is explained in this answer.
The problem is the use of -Path rather than -LiteralPath, because -Path interprets its argument as a wildcard expression.
Therefore, the [foo] in $env:[foo] - rather than being used as-is - is interpreted as a wildcard expression that matches a single character that is either f or o ([foo] is a character set or range ([...]) that matches any one of the (distinct) characters inside - see about_Wildcards).
On assigning to $env:[foo], the logic of Set-Content -Path requires that a wildcard-based path resolve to something existing, even though you're generally not required to explicitly create environment variables; e.g., $env:NoSuchVarExistsYet = 'new' works just fine.
Workaround:
Use double(!)-`-escaping of the wildcard metacharacters:
# Namespace variable notation only works with if you
# double(!)-backtick-escape the wildcard metacharacters:
# Assign to / implicitly create env. var '[foo]'
$env:``[foo``] = 'bar'
# Get its value.
$env:``[foo``]
Note:
Escaping shouldn't be required at all, because there is no good reason to treat paths that conceptually identify a given, known item as wildcard expressions - see this GitHub issue.
That double
`-escaping is needed is an added quirk - see this GitHub issue.Another workaround - one that doesn't involve escaping - is to use
Set-Content -LiteralPath env:[foo] barandGet-Content -LiteralPath env:[foo], but that is both verbose and slow.
As for the other syntax variations you tried:
$env:$[foo]="bar"
Since your variable reference isn't ...-enclosed as a whole (except for the initial $), the token that follows the : is only allowed to contain characters that do not require escaping - and $, and all violate that rule.
...-enclosing the entire path -$env:[foo]- solves the syntax problem, but runs into the problem detailed above.
Set-Item -LiteralPath env:$[foo] -Value "bar"
This does not work in general, because string expansion is applied beforehand here - it is as if you had passed "env:$[foo]": the reference to a (regular) variable named $[foo] is expanded (replaced with its value) and in effect appended to literal env:, before handing the result to Set-Item.
If such a regular variable doesn't exist, what Set-Item sees is just env: (because non-existent variables default to $null, which becomes the empty string in a string context), which causes an error due to the lack of variable name.
By contrast, the following would set an environment variable named unrelated instead:
# Create a regular variable literally named '[foo]'.
$[foo] = 'unrelated'
# !! The following sets env:unrelated, i.e., env. var 'unrelated',
# !! due to the string expansion that is performed on the -LiteralPath
# !! argument up front.
Set-Item -LiteralPath env:$[foo] bar
$env:unrelated # -> 'bar'
The same applies to Get-Item -LiteralPath env:$[foo] and Set-Item -LiteralPath env:$[foo]2 -Value "bar".
add a comment |
Written as of PowerShell Core 6.2.0
The reason is that PowerShell treats the following:
$<drive>:<name>
as if you had specified:
Get-Content -Path <drive>:<name> # or, with assignment, Set-Content -Path ...
This notation - though often used with the Env: drive (e.g., $env:Path) - is little-known as a general paradigm named namespace variable notation, which is explained in this answer.
The problem is the use of -Path rather than -LiteralPath, because -Path interprets its argument as a wildcard expression.
Therefore, the [foo] in $env:[foo] - rather than being used as-is - is interpreted as a wildcard expression that matches a single character that is either f or o ([foo] is a character set or range ([...]) that matches any one of the (distinct) characters inside - see about_Wildcards).
On assigning to $env:[foo], the logic of Set-Content -Path requires that a wildcard-based path resolve to something existing, even though you're generally not required to explicitly create environment variables; e.g., $env:NoSuchVarExistsYet = 'new' works just fine.
Workaround:
Use double(!)-`-escaping of the wildcard metacharacters:
# Namespace variable notation only works with if you
# double(!)-backtick-escape the wildcard metacharacters:
# Assign to / implicitly create env. var '[foo]'
$env:``[foo``] = 'bar'
# Get its value.
$env:``[foo``]
Note:
Escaping shouldn't be required at all, because there is no good reason to treat paths that conceptually identify a given, known item as wildcard expressions - see this GitHub issue.
That double
`-escaping is needed is an added quirk - see this GitHub issue.Another workaround - one that doesn't involve escaping - is to use
Set-Content -LiteralPath env:[foo] barandGet-Content -LiteralPath env:[foo], but that is both verbose and slow.
As for the other syntax variations you tried:
$env:$[foo]="bar"
Since your variable reference isn't ...-enclosed as a whole (except for the initial $), the token that follows the : is only allowed to contain characters that do not require escaping - and $, and all violate that rule.
...-enclosing the entire path -$env:[foo]- solves the syntax problem, but runs into the problem detailed above.
Set-Item -LiteralPath env:$[foo] -Value "bar"
This does not work in general, because string expansion is applied beforehand here - it is as if you had passed "env:$[foo]": the reference to a (regular) variable named $[foo] is expanded (replaced with its value) and in effect appended to literal env:, before handing the result to Set-Item.
If such a regular variable doesn't exist, what Set-Item sees is just env: (because non-existent variables default to $null, which becomes the empty string in a string context), which causes an error due to the lack of variable name.
By contrast, the following would set an environment variable named unrelated instead:
# Create a regular variable literally named '[foo]'.
$[foo] = 'unrelated'
# !! The following sets env:unrelated, i.e., env. var 'unrelated',
# !! due to the string expansion that is performed on the -LiteralPath
# !! argument up front.
Set-Item -LiteralPath env:$[foo] bar
$env:unrelated # -> 'bar'
The same applies to Get-Item -LiteralPath env:$[foo] and Set-Item -LiteralPath env:$[foo]2 -Value "bar".
add a comment |
Written as of PowerShell Core 6.2.0
The reason is that PowerShell treats the following:
$<drive>:<name>
as if you had specified:
Get-Content -Path <drive>:<name> # or, with assignment, Set-Content -Path ...
This notation - though often used with the Env: drive (e.g., $env:Path) - is little-known as a general paradigm named namespace variable notation, which is explained in this answer.
The problem is the use of -Path rather than -LiteralPath, because -Path interprets its argument as a wildcard expression.
Therefore, the [foo] in $env:[foo] - rather than being used as-is - is interpreted as a wildcard expression that matches a single character that is either f or o ([foo] is a character set or range ([...]) that matches any one of the (distinct) characters inside - see about_Wildcards).
On assigning to $env:[foo], the logic of Set-Content -Path requires that a wildcard-based path resolve to something existing, even though you're generally not required to explicitly create environment variables; e.g., $env:NoSuchVarExistsYet = 'new' works just fine.
Workaround:
Use double(!)-`-escaping of the wildcard metacharacters:
# Namespace variable notation only works with if you
# double(!)-backtick-escape the wildcard metacharacters:
# Assign to / implicitly create env. var '[foo]'
$env:``[foo``] = 'bar'
# Get its value.
$env:``[foo``]
Note:
Escaping shouldn't be required at all, because there is no good reason to treat paths that conceptually identify a given, known item as wildcard expressions - see this GitHub issue.
That double
`-escaping is needed is an added quirk - see this GitHub issue.Another workaround - one that doesn't involve escaping - is to use
Set-Content -LiteralPath env:[foo] barandGet-Content -LiteralPath env:[foo], but that is both verbose and slow.
As for the other syntax variations you tried:
$env:$[foo]="bar"
Since your variable reference isn't ...-enclosed as a whole (except for the initial $), the token that follows the : is only allowed to contain characters that do not require escaping - and $, and all violate that rule.
...-enclosing the entire path -$env:[foo]- solves the syntax problem, but runs into the problem detailed above.
Set-Item -LiteralPath env:$[foo] -Value "bar"
This does not work in general, because string expansion is applied beforehand here - it is as if you had passed "env:$[foo]": the reference to a (regular) variable named $[foo] is expanded (replaced with its value) and in effect appended to literal env:, before handing the result to Set-Item.
If such a regular variable doesn't exist, what Set-Item sees is just env: (because non-existent variables default to $null, which becomes the empty string in a string context), which causes an error due to the lack of variable name.
By contrast, the following would set an environment variable named unrelated instead:
# Create a regular variable literally named '[foo]'.
$[foo] = 'unrelated'
# !! The following sets env:unrelated, i.e., env. var 'unrelated',
# !! due to the string expansion that is performed on the -LiteralPath
# !! argument up front.
Set-Item -LiteralPath env:$[foo] bar
$env:unrelated # -> 'bar'
The same applies to Get-Item -LiteralPath env:$[foo] and Set-Item -LiteralPath env:$[foo]2 -Value "bar".
Written as of PowerShell Core 6.2.0
The reason is that PowerShell treats the following:
$<drive>:<name>
as if you had specified:
Get-Content -Path <drive>:<name> # or, with assignment, Set-Content -Path ...
This notation - though often used with the Env: drive (e.g., $env:Path) - is little-known as a general paradigm named namespace variable notation, which is explained in this answer.
The problem is the use of -Path rather than -LiteralPath, because -Path interprets its argument as a wildcard expression.
Therefore, the [foo] in $env:[foo] - rather than being used as-is - is interpreted as a wildcard expression that matches a single character that is either f or o ([foo] is a character set or range ([...]) that matches any one of the (distinct) characters inside - see about_Wildcards).
On assigning to $env:[foo], the logic of Set-Content -Path requires that a wildcard-based path resolve to something existing, even though you're generally not required to explicitly create environment variables; e.g., $env:NoSuchVarExistsYet = 'new' works just fine.
Workaround:
Use double(!)-`-escaping of the wildcard metacharacters:
# Namespace variable notation only works with if you
# double(!)-backtick-escape the wildcard metacharacters:
# Assign to / implicitly create env. var '[foo]'
$env:``[foo``] = 'bar'
# Get its value.
$env:``[foo``]
Note:
Escaping shouldn't be required at all, because there is no good reason to treat paths that conceptually identify a given, known item as wildcard expressions - see this GitHub issue.
That double
`-escaping is needed is an added quirk - see this GitHub issue.Another workaround - one that doesn't involve escaping - is to use
Set-Content -LiteralPath env:[foo] barandGet-Content -LiteralPath env:[foo], but that is both verbose and slow.
As for the other syntax variations you tried:
$env:$[foo]="bar"
Since your variable reference isn't ...-enclosed as a whole (except for the initial $), the token that follows the : is only allowed to contain characters that do not require escaping - and $, and all violate that rule.
...-enclosing the entire path -$env:[foo]- solves the syntax problem, but runs into the problem detailed above.
Set-Item -LiteralPath env:$[foo] -Value "bar"
This does not work in general, because string expansion is applied beforehand here - it is as if you had passed "env:$[foo]": the reference to a (regular) variable named $[foo] is expanded (replaced with its value) and in effect appended to literal env:, before handing the result to Set-Item.
If such a regular variable doesn't exist, what Set-Item sees is just env: (because non-existent variables default to $null, which becomes the empty string in a string context), which causes an error due to the lack of variable name.
By contrast, the following would set an environment variable named unrelated instead:
# Create a regular variable literally named '[foo]'.
$[foo] = 'unrelated'
# !! The following sets env:unrelated, i.e., env. var 'unrelated',
# !! due to the string expansion that is performed on the -LiteralPath
# !! argument up front.
Set-Item -LiteralPath env:$[foo] bar
$env:unrelated # -> 'bar'
The same applies to Get-Item -LiteralPath env:$[foo] and Set-Item -LiteralPath env:$[foo]2 -Value "bar".
edited Mar 25 at 21:32
answered Mar 25 at 18:07
mklement0mklement0
148k24 gold badges269 silver badges303 bronze badges
148k24 gold badges269 silver badges303 bronze badges
add a comment |
add a comment |
Got a question that you can’t ask on public Stack Overflow? Learn more about sharing private information with Stack Overflow for Teams.
Got a question that you can’t ask on public Stack Overflow? Learn more about sharing private information with Stack Overflow for Teams.
Thanks for contributing an answer to Stack Overflow!
- 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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55343828%2fhow-to-assign-and-reference-environment-variables-containing-square-brackets-in%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
Great question; as an aside:
Get-Item -LiteralPath env:$[foo]andSet-Item -LiteralPath env:$[foo] -Value "bar"do not work either, or at least won't work they way you expect, due to up-front string expansion.– mklement0
Mar 25 at 19:50