You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#调用Azure Run Command API在Linux VM执行Shell脚本相关问题咨询

问题解决方案

1. 仅返回202状态码无执行结果的解决

原因

Azure 虚拟机Run Command接口为异步设计,返回202状态码仅代表命令提交成功,而非执行完成,不会在首次响应中直接返回执行结果。

解决步骤

  • 首次请求返回202后,从响应头的Azure-AsyncOperation字段获取执行状态查询地址
  • 按固定间隔(推荐2-3秒)轮询该查询地址,直到返回结果中的status字段变为Succeeded或Failed
  • 执行成功后,从返回结果的properties.output.value字段读取命令执行的标准输出、标准错误内容

2. 给shell脚本传递参数的实现

实现方式

RunShellScript命令支持parameters参数,你可以将需要传入myscript.sh的参数按顺序添加到该字段中,脚本内直接通过$1、$2等位置变量读取参数即可。

请求Body构造要求

  • 保留commandId为RunShellScript
  • script字段填写你虚拟机上myscript.sh的绝对路径,例如/home/user/myscript.sh
  • 新增parameters列表,每个参数为包含name和value的对象,参数会按你添加的顺序传入脚本

修改后的完整C#代码示例

using (var client = new HttpClient())
{
    // 构造请求Body,包含脚本路径和传入参数
    Body body = new Body
    {
        commandId = "RunShellScript",
        // 替换为你虚拟机上myscript.sh的实际绝对路径
        script = new List<string> { "/home/youruser/myscript.sh" },
        // 传入参数,按顺序对应脚本的$1、$2...
        parameters = new List<Parameter>
        {
            new Parameter { name = "arg1", value = "第一个参数值" },
            new Parameter { name = "arg2", value = "第二个参数值" }
        }
    };

    // 生成Bearer Token
    var azureServiceTokenProvider = new AzureServiceTokenProvider();
    string managementApiUrl = "https://management.azure.com/";
    var accessToken = await azureServiceTokenProvider.GetAccessTokenAsync(managementApiUrl, "你的租户ID");
            
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);

    // 调用POST提交命令
    HttpResponseMessage response = await client.PostAsJsonAsync("https://management.azure.com/subscriptions/你的订阅ID/resourceGroups/你的资源组名/providers/Microsoft.Compute/virtualMachines/simpleLinuxVM/runCommand?api-version=2021-03-01", body);

    if (response.StatusCode == HttpStatusCode.Accepted)
    {
        // 获取异步查询地址
        string asyncOperationUrl = response.Headers.GetValues("Azure-AsyncOperation").FirstOrDefault();
        string operationResult = null;

        // 轮询查询执行状态
        while (true)
        {
            HttpResponseMessage statusResponse = await client.GetAsync(asyncOperationUrl);
            if (statusResponse.IsSuccessStatusCode)
            {
                operationResult = await statusResponse.Content.ReadAsStringAsync();
                // 解析状态,可使用JsonNode或者自定义类解析返回内容
                var statusJson = JsonNode.Parse(operationResult);
                string status = statusJson["status"].GetValue<string>();

                if (status == "Succeeded" || status == "Failed")
                {
                    break;
                }
            }
            // 等待2秒再轮询
            await Task.Delay(2000);
        }

        // 输出最终执行结果
        Console.WriteLine($"执行结果:{operationResult}");
    }
    else
    {
        Console.WriteLine($"请求失败,状态码:{response.StatusCode}");
        string responseContent = await response.Content.ReadAsStringAsync();
        Console.WriteLine(responseContent);
    }
}

// 用到的自定义类定义参考
public class Body
{
    public string commandId { get; set; }
    public List<string> script { get; set; }
    public List<Parameter> parameters { get; set; }
}

public class Parameter
{
    public string name { get; set; }
    public string value { get; set; }
}

内容的提问来源于stack exchange,提问作者MSE Black

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 06:57:03