Linux调用Google Speech to Text报凭证环境变量未定义错误
Linux不需要针对Google Speech to Text做额外的特殊适配,这个报错的核心原因是当前Linux运行环境下,Google SDK没有找到有效的服务账号凭证:SDK会按优先级依次读取进程内的GOOGLE_APPLICATION_CREDENTIALS环境变量指向的密钥文件、本地gcloud工具配置的默认凭证、云主机元数据服务挂载的临时凭证,三个位置都没拿到有效凭证就会抛出你看到的IO异常。
第一步:上传并校验密钥文件
把你Windows环境下使用的Google服务账号JSON密钥文件上传到Linux服务器,建议存到固定路径比如/opt/keys/google-stt-key.json,路径不要带中文、特殊空格字符。
执行以下命令给运行Java程序的用户分配密钥文件的读权限,同时避免权限过宽被SDK拦截:chmod 400 /opt/keys/google-stt-key.json chown 你的Java程序运行用户:你的Java程序运行用户组 /opt/keys/google-stt-key.json可以用
jq工具校验密钥文件是否损坏:cat /opt/keys/google-stt-key.json | jq .,如果能正常输出JSON结构说明文件完好,报错就重新上传密钥。第二步:配置环境变量,根据你启动程序的方式选对应配置方法
- 临时测试(仅当前终端会话生效):在启动Java程序的终端里直接执行:
执行完不要关闭当前终端,直接在同一个终端窗口启动Java程序即可。export GOOGLE_APPLICATION_CREDENTIALS="/opt/keys/google-stt-key.json" - 手动终端启动永久生效:如果平时是手动开终端启动程序,就把上面的export命令追加到你所用shell的配置文件末尾,比如用bash就写
~/.bashrc,用zsh就写~/.zshrc,写完执行source 对应配置文件路径加载配置即可。 - 重点注意:如果是用systemd、supervisor这类进程托管工具把Java程序配成系统服务运行,shell配置文件里的环境变量不会被服务进程加载,必须在服务配置文件里单独声明环境变量。比如systemd的service配置里要在[Service]段加:
改完执行Environment="GOOGLE_APPLICATION_CREDENTIALS=/opt/keys/google-stt-key.json"systemctl daemon-reload重启对应服务才会生效。
- 临时测试(仅当前终端会话生效):在启动Java程序的终端里直接执行:
第三步:校验配置
在启动程序的同一上下文(同终端/服务环境)里执行echo $GOOGLE_APPLICATION_CREDENTIALS,确认输出路径和你实际存放密钥的路径完全一致,再执行ls 输出的路径确认文件存在可读,排除路径写错、文件丢失的低级问题。
如果不想在不同系统里单独配环境变量,可以在代码初始化SpeechClient的时候手动加载指定路径的密钥文件,直接传入凭证对象初始化客户端,避免依赖系统层面的环境变量配置,注意不要把密钥文件提交到公共代码仓库造成泄露。
- 配完环境变量后新开终端启动程序,导致新终端没有加载到配置的变量
- 密钥文件存到了/root这类只有root用户能访问的路径下,普通用户运行程序时读不到文件
- 传输密钥文件时用了文本传输模式,导致JSON格式损坏、换行符异常,SDK解析密钥失败
- 用sudo启动程序的时候,sudo默认不会继承当前用户的环境变量,需要加
-E参数保留环境变量,或者直接给root用户也配置对应环境变量
内容的提问来源于stack exchange,提问作者huiling liao

