fix
This commit is contained in:
parent
150e854f40
commit
9d601791ae
|
|
@ -32,9 +32,12 @@ public class SubprocessScriptExecutor : IScriptExecutor
|
|||
var workingDir = ExecutionHelpers.ResolveWorkingDir(invocation);
|
||||
var entryPath = Path.Combine(workingDir, invocation.EntryFile);
|
||||
|
||||
var (executable, args) = ResolveInterpreter(entryPath);
|
||||
args.Add(entryPath);
|
||||
|
||||
var output = await ProcessRunner.RunAsync(
|
||||
_executable,
|
||||
new[] { entryPath },
|
||||
executable,
|
||||
args,
|
||||
workingDir,
|
||||
ExecutionHelpers.BuildEnvironment(invocation),
|
||||
invocation.Input,
|
||||
|
|
@ -50,6 +53,54 @@ public class SubprocessScriptExecutor : IScriptExecutor
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Chooses the interpreter for a shell script. A shell script may declare a
|
||||
/// specific shell in its shebang (e.g. <c>#!/usr/bin/env bash</c>); running it
|
||||
/// under the registered POSIX <c>sh</c> instead would reject bash-only syntax
|
||||
/// such as <c>set -o pipefail</c>. When the shebang names an interpreter that
|
||||
/// is available on PATH we honour it; otherwise (no shebang, unknown
|
||||
/// interpreter) we fall back to the registered default so behaviour is
|
||||
/// unchanged for plain POSIX scripts.
|
||||
/// </summary>
|
||||
private (string Executable, List<string> Args) ResolveInterpreter(string entryPath)
|
||||
{
|
||||
var fallback = (_executable, new List<string>());
|
||||
if (!string.Equals(_language, "shell", StringComparison.Ordinal) || !File.Exists(entryPath))
|
||||
return fallback;
|
||||
|
||||
try
|
||||
{
|
||||
string? firstLine;
|
||||
using (var reader = new StreamReader(entryPath))
|
||||
firstLine = reader.ReadLine();
|
||||
|
||||
if (firstLine is null || !firstLine.StartsWith("#!", StringComparison.Ordinal))
|
||||
return fallback;
|
||||
|
||||
var parts = firstLine.Substring(2).Trim()
|
||||
.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length == 0)
|
||||
return fallback;
|
||||
|
||||
var candidate = parts[0];
|
||||
var extra = parts.Skip(1).ToList();
|
||||
|
||||
// "#!/usr/bin/env bash" -> run "bash" (env resolves it via PATH).
|
||||
if (string.Equals(Path.GetFileName(candidate), "env", StringComparison.Ordinal) && extra.Count > 0)
|
||||
{
|
||||
candidate = extra[0];
|
||||
extra.RemoveAt(0);
|
||||
}
|
||||
|
||||
var resolved = ProcessRunner.FindInPath(candidate);
|
||||
return resolved is null ? fallback : (resolved, extra);
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
return fallback;
|
||||
}
|
||||
}
|
||||
|
||||
private static int ParseInt(string? text, int fallback)
|
||||
=> int.TryParse(text, out var value) && value > 0 ? value : fallback;
|
||||
}
|
||||
|
|
|
|||
11
appsettings.Development.json
Normal file
11
appsettings.Development.json
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"Workflows": {
|
||||
"ChatApiUrl": "http://localhost:5258"
|
||||
}
|
||||
}
|
||||
|
|
@ -82,6 +82,28 @@ public class SubprocessScriptExecutorTests
|
|||
Assert.Contains("time limit", result.Error);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Shell_honours_bash_shebang_for_bash_only_scripts()
|
||||
{
|
||||
if (ProcessRunner.FindInPath("bash") is null)
|
||||
return; // no bash on this host — the fallback path is covered elsewhere
|
||||
|
||||
using var dir = new TempDir();
|
||||
dir.Write("task.sh", """
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
cat >/dev/null || true
|
||||
echo '{"ok":true}'
|
||||
""");
|
||||
|
||||
var result = await Shell().ExecuteAsync(
|
||||
Invocation.For("shell", "task.sh", "{}", dir.Path), default);
|
||||
|
||||
Assert.True(result.Success, result.Error);
|
||||
using var output = JsonDocument.Parse(result.Output!);
|
||||
Assert.True(output.RootElement.GetProperty("ok").GetBoolean());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Python_reads_stdin_and_returns_json_output()
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue