I have a python script:
# temp.py
print("foo\nbar")
I can run this in powershell:
> python .\temp.py
foo
bar
I want to set the environment variable FOO to the output of this python script. However, doing so changes the newline to a space:
> $env:FOO=$(python .\temp.py)
> $env:FOO
foo bar
What I’ve Tried
Verify that environment variables can contain newlines:
> echo "foo`nbar"
foo
bar
> $env:FOO2=$(echo "foo`nbar")
> $env:FOO2
foo
bar
… so it seems like the issue has something to do with execution of a python script?
Verify that the subexpression operator $() is not modifying the python script output:
> $(python .\temp.py)
foo
bar
echoing the output of the python script seems to exhibit the same behavior:
> echo "$(python .\temp.py)"
foo bar
… but not if I exclude the quotes:
> echo $(python .\temp.py)
foo
bar
Workaround
Base64 encoding the string bypasses bypasses this issue. However, I still wonder what could be causing this?
My powershell version is 5.1.22621.963
>Solution :
Use the following:
$env:FOO = (python .\temp.py) -join "`n"
-
PowerShell reports stdout output from external programs such as
pythonline by line, which, when captured via$(...)or(...)results in an array of lines (for two or more lines). -
If you try to assign the result as-is to an environment variable, PowerShell implicitly stringifies the array, which means that it joins its elements with a space as the separator, so that lines
fooandbarturn into a string with verbatim contentfoo bar; that is, the newlines are replaced with spaces. -
By explicitly joining the elements with a (LF-only) newline (expressed as
"`n"via an expandable PowerShell string) using the-joinoperator, an explicit multi-line string is constructed up front, which can the be assigned to an – invariably string-typed – environment variable.