protoc处理输入文件报错,请求排查Shell脚本问题
protoc脚本执行报错排查
输入文件、输出文件及生成脚本均位于同一目录下,编写了如下Shell脚本:
#!/usr/bin/env bash dir_name="$(cd "$(dirname "${BASH_SOURCE}")" && PWD)" protoc --go_out="$dir_name" --go-grpc_out="$dir_name" "${dir_name}/myservice.proto"
执行该脚本后出现以下错误:
alex@alex yoda % /Users/alex/codes/yoda/yoda.ores.int/src/proto/generate.sh /Users/alex/codes/yoda/yoda.ores.int/src/proto /Users/alex/codes/yoda/yoda.ores.int/src/proto/myservice.proto: File does not reside within any path specified using --proto_path (or -I). You must specify a --proto_path which encompasses this file. Note that the proto_path must be an exact prefix of the .proto file names -- protoc is too dumb to figure out when two paths (e.g. absolute and relative) are equivalent (it's harder than you think).
错误核心提示(翻译后):
文件不在任何通过
--proto_path(或-I)指定的路径范围内。你必须指定一个包含该文件的--proto_path。注意,proto_path必须是.proto文件名的精确前缀——protoc无法识别绝对路径和相对路径这类等价情况(这比想象中复杂)。
对应的.proto文件内容如下:
// myservice.proto syntax = "proto3"; package myservice; // Define your gRPC service. service MyService { rpc SendMessage (MessageRequest) returns (MessageResponse); } // Define your request and response message types. message MessageRequest { string message_data = 1; // Add more fields as needed } message MessageResponse { string status = 1; // Add more fields as needed }
问题原因及解决方法
原因
protoc默认将当前工作目录作为--proto_path(即-I参数)的路径,而你传入的是.proto文件的绝对路径,这个绝对路径的前缀和默认的相对路径前缀无法匹配,导致protoc认为该文件不在指定的proto_path范围内,从而报错。
解决方法
有两种可行的修正方式:
方式一:显式指定--proto_path参数
在protoc命令中添加--proto_path="$dir_name",同时将.proto文件名改为相对该路径的形式(直接写myservice.proto):
#!/usr/bin/env bash dir_name="$(cd "$(dirname "${BASH_SOURCE}")" && PWD)" protoc --proto_path="$dir_name" --go_out="$dir_name" --go-grpc_out="$dir_name" "myservice.proto"
方式二:切换到脚本所在目录执行
先切换到.proto文件所在的目录,这样protoc默认的--proto_path就是当前目录,无需额外指定,同时输出路径用.表示当前目录,逻辑更简洁:
#!/usr/bin/env bash # 切换到脚本所在目录,失败则退出 cd "$(dirname "${BASH_SOURCE}")" || exit 1 protoc --go_out="." --go-grpc_out="." "myservice.proto"
内容的提问来源于stack exchange,提问作者Alexander Mills
相关产品推荐
相关产品推荐

