@@ -190,10 +190,18 @@ private static void VerifyEnvScriptWorks(string shell, string installPath, strin
190190
191191 static string Escape ( string s ) => s . Replace ( "'" , "'\\ ''" ) ;
192192
193+ // Use a temp file to capture dotnetup output instead of process substitution.
194+ // Process substitution failures are silently ignored by `source`, making
195+ // debugging impossible when dotnetup can't find its runtime.
196+ string envScriptOutput = Path . Combine ( tempRoot , $ "dotnetup-env-{ shell } .sh") ;
197+
193198 scriptPath = Path . Combine ( tempRoot , $ "test-env-{ shell } .sh") ;
194199 scriptContent = $@ "#!/bin/{ shell }
195200set -e
196- source <('{ Escape ( dotnetupPath ) } ' print-env-script --shell { shell } --dotnet-install-path '{ Escape ( installPath ) } ')
201+ # Generate env script to a file (errors will be caught by set -e)
202+ '{ Escape ( dotnetupPath ) } ' print-env-script --shell { shell } --dotnet-install-path '{ Escape ( installPath ) } ' > '{ Escape ( envScriptOutput ) } '
203+ # Source the generated env script
204+ source '{ Escape ( envScriptOutput ) } '
197205# Clear cached dotnet path to ensure we use the newly configured PATH
198206hash -d dotnet 2>/dev/null || true
199207# Capture versions into variables first to avoid nested quoting issues on macOS bash 3.2
@@ -245,6 +253,17 @@ private static void VerifyEnvScriptWorks(string shell, string installPath, strin
245253 process . StartInfo . RedirectStandardError = true ;
246254 process . StartInfo . WorkingDirectory = tempRoot ;
247255
256+ // output which is a framework-dependent AppHost. Ensure DOTNET_ROOT is set so
257+ // the AppHost can locate the runtime. On CI each script step gets a fresh shell,
258+ // so DOTNET_ROOT from the restore step isn't inherited. The env script sourced
259+ // later in the test will overwrite DOTNET_ROOT with the test install path.
260+ string ? currentDotnetRoot = Environment . GetEnvironmentVariable ( "DOTNET_ROOT" )
261+ ?? ( Environment . ProcessPath is string processPath ? Path . GetDirectoryName ( processPath ) : null ) ;
262+ if ( currentDotnetRoot != null )
263+ {
264+ process . StartInfo . Environment [ "DOTNET_ROOT" ] = currentDotnetRoot ;
265+ }
266+
248267 var outputBuilder = new StringBuilder ( ) ;
249268 var errorBuilder = new StringBuilder ( ) ;
250269
0 commit comments