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
echo
ing 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
CodePudding user response:
Use the following:
$env:FOO = (python .\temp.py) -join "`n"
PowerShell reports stdout output from external programs such as
python
line 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 - which is invariably string-typed - PowerShell implicitly stringifies the array, which means that it joins its elements with a space as the separator, so that lines
foo
andbar
turn 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-join
operator, an explicit multi-line string is constructed up front, which can then be assigned to an environment variable.