Zend certified PHP/Magento developer

WSL2 interop issue causes premature exit from read loop in shell script

Summary

Using read loop that runs a windows executable in WSL shell script causes it to exit the loop after the first iteration.

Details

I’ve been quite baffled by what appears to be an interoperability issue with running windows executables from a shell script in WSL2. The following while loop should print 3 lines but it will only print “line 1”. It has been tested on Ubuntu 20.04 in dash, bash, and zsh.

while read -r line; do
       powershell.exe /C "echo "${line}""
done << EOF
line 1
line 2
line 3
EOF

This issue also occurs when reading lines from a file instead of a heredoc even if that file has windows line endings. Note that if powershell were changed to /bin/bash or any other native executable this would print 3 lines. Also powershell could be replaced with any windows executable cmd.exe, explorer.exe, etc and it would still only run the first iteration. This appears to be a problem with read specifically since this loop will work fine.

for line in "line 1" "line 2" "line 3"
do
    powershell.exe /C "echo "${line}""
done

Work-around

Thanks to this post I have discovered a work around is to pipe through a dummy command: echo "" | cmd.exe /C "echo "${line}"". A note about this fix is that only piping seems to work. Redirecting the output or running it through another layer of bash does not: /bin/bash -c "cmd.exe /C "echo ${line}"". I am partially posting this for improved visibility for anyone having this issue in the future, but I am still curious if anyone has any insight as to why this issue exists (perhaps due to line endings?). Thank you!