use Open3.popen3 instead of IO.popen to avoid env issue