Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

PowerShell setting environment variable to subexpression discards newline

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:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

> $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 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, PowerShell implicitly stringifies the array, which means that it joins its elements with a space as the separator, so that lines foo and bar turn into a string with verbatim content foo 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 the be assigned to an – invariably string-typed – environment variable.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading