简体   繁体   中英

what is var=${var:-word} bash equivalent in powershell

Given this bash code:

HELLO =${HELLO:-hello}

the variable HELLO takes a value from the HELLO environment variable if it exists. Otherwise it sets the value to be hello .

What is the Powershell equivalent?

PowerShell, as of Windows PowerShell v5.1 / PowerShell Core 6.1.0, has no equivalent functionality to Bash's parameter expansion feature, of which ${HELLO:-hello} is an instance [1] .

Note:

  • In Bash, environment variables and Bash's own shell variables share the same namespace, and environment variables are automatically exposed as shell variables.

  • In PowerShell, only PowerShell's own variables can be referenced directly - eg, $myVar - whereas referencing environment variables requires explicit use of the env: namespace - eg, $env:PATH

The solutions below focus mostly on PowerShell's own variables, but the techniques can analogously be applied to environment variables.
Note that while environment variables are always strings , PowerShell variables can be of any (.NET) type .


To emulate HELLO=${HELLO:-hello} in PowerShell, use:

# To target an *environment* variable, use $env:HELLO instead.
$HELLO = if ("$HELLO") { $HELLO } else { 'hello' }

Note the "..." around $HELLO in the conditional, which ensures that the value is converted to a string before coercing it to a Boolean [2] : that way, both the case of $HELLO not having been defined (or explicitly containing $null ) and the variable containing the empty string evaluate to $False , which parallels Bash's behavior.

Without the stringification with "..." , non-string values such as 0 or $False too would trigger the else branch.
However, if you only ever expect $HELLO to contain a string value, if any, you can omit the "..." .

Similarly, the above also works with environment variables , but since they are always strings , you don't strictly need the enclosing "..." in that case:

$env:HELLO = if ($env:HELLO) { $env:HELLO } else { 'hello' }

In the simple case of leaving any preexisting value of $HELLO alone and only assigning a default value in the in the absence of the former:

if (-not "$HELLO") { $HELLO = 'hello' }

# As an environment variable
if (-not $env:HELLO) { $env:HELLO = 'hello' }

To emulate HELLO=${HELLO-hello} - note the absence of the : -, use:

$HELLO = if ($null -eq $HELLO) { 'hello' } else { $HELLO }

# Simplified
if ($null -eq $HELLO) { $HELLO = 'hello' }

This covers only the case of $HELLO not being defined (and also it explicitly containing $null , but that isn't common).

Note that the $null is deliberately used as the LHS , which is a good habit to form in PowerShell to avoid surprises if the LHS happens to be an array , in which case -eq acts an array filter rather than returning a Boolean.


[1] While Bash's parameter expansion will likely never be implemented in PowerShell as such , simply because it is not a good syntactic fit for the language, providing concise, PowerShell-idiomatic analogs to Bash's ${HELLO-hello} and ${HELLO=hello} is being discussed, as $HELLO ?? 'hello' $HELLO ?? 'hello' and $HELLO ?= 'hello' - see this GitHub issue .

[2] PowerShell coerces any string to a Boolean with this simple rule: if the string is empty , it evaluates to $False ; if it is non-empty - whatever its contents - it evaluates to $True .

The most straight forward way is :

$Hello = If($env:hello -eq $null){"WORLD"}else{$env:hello}

Or you can make a alias if you plan on using it a lot

function IfNull($If, $Else){
    if($If -eq $Null){
        $Else
    }else{
        $If
    }
}

Add-Alias "??" IfNull

$Hello = ?? $env:hello "World2"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM