关键词:Jenkins、Unable to produce a script file、UnmappableCharacterException、IOException: Failed to create a temp file on
0x00 问题描绘
由于运用的 Jenkins 存在安全漏洞(详见 Jenkins Security Advisory 2023-03-08),需求升级到已解决安全漏洞的新版本,更新后运转任务时呈现了报错:FATAL: Unable to produce a script file
详细的报错日志如下:
# 拉取代码的 Commit 信息
16:21:35 Commit message: "feat: ????"
# 仓库信息
16:21:35 FATAL: Unable to produce a script file
16:21:35 java.nio.charset.UnmappableCharacterException: Input length = 1
16:21:35 at java.base/java.nio.charset.CoderResult.throwException(CoderResult.java:275)
16:21:35 at java.base/sun.nio.cs.StreamEncoder.implWrite(StreamEncoder.java:306)
16:21:35 at java.base/sun.nio.cs.StreamEncoder.implWrite(StreamEncoder.java:281)
16:21:35 at java.base/sun.nio.cs.StreamEncoder.write(StreamEncoder.java:125)
16:21:35 at java.base/java.io.OutputStreamWriter.write(OutputStreamWriter.java:208)
16:21:35 at java.base/java.io.BufferedWriter.flushBuffer(BufferedWriter.java:120)
16:21:35 at java.base/java.io.BufferedWriter.close(BufferedWriter.java:268)
16:21:35 at hudson.FilePath$CreateTextTempFile.invoke(FilePath.java:1658)
16:21:35 at hudson.FilePath$CreateTextTempFile.invoke(FilePath.java:1628)
16:21:35 at hudson.FilePath.act(FilePath.java:1198)
16:21:35 at hudson.FilePath.act(FilePath.java:1181)
16:21:35 at hudson.FilePath.createTextTempFile(FilePath.java:1622)
16:21:35 Caused: java.io.IOException: Failed to create a temp file on /var/jenkins_home/workspace/xxx
16:21:35 at hudson.FilePath.createTextTempFile(FilePath.java:1624)
16:21:35 at hudson.tasks.CommandInterpreter.createScriptFile(CommandInterpreter.java:202)
16:21:35 at hudson.tasks.CommandInterpreter.perform(CommandInterpreter.java:120)
16:21:35 at hudson.tasks.CommandInterpreter.perform(CommandInterpreter.java:92)
16:21:35 at hudson.tasks.BuildStepMonitor$1.perform(BuildStepMonitor.java:20)
16:21:35 at hudson.model.AbstractBuild$AbstractBuildExecution.perform(AbstractBuild.java:818)
16:21:35 at hudson.model.Build$BuildExecution.build(Build.java:199)
16:21:35 at hudson.model.Build$BuildExecution.doRun(Build.java:164)
16:21:35 at hudson.model.AbstractBuild$AbstractBuildExecution.run(AbstractBuild.java:526)
16:21:35 at hudson.model.Run.execute(Run.java:1900)
16:21:35 at hudson.model.FreeStyleBuild.run(FreeStyleBuild.java:44)
16:21:35 at hudson.model.ResourceController.execute(ResourceController.java:101)
16:21:35 at hudson.model.Executor.run(Executor.java:442)
16:21:35 Build step 'Execute shell' marked build as failure
0x01 定位原因
根本原因隐藏在日志信息里:
- 首要,能够看到
Commit message: "feat: ????"
中的中文内容变成了乱码????
。 - 从仓库信息里
java.nio.charset.UnmappableCharacterException: Input length = 1
可知,这是个和字符集相关的报错信息:
这个过错是由于Java运转时无法将一个输入的字符映射为所需求的字符集(通常是Unicode)而引起的。或许会产生这种状况:
输入的文本包含了一个你运用的字符集无法映射的字符。 假如文本在不同的平台上被创立和传输,则或许会产生此过错,因为每个平台运用的默认字符集或许不同。 为了解决这个过错,你能够测验以下方法:
- 查看你的字符集: 在你的代码中,确保你所运用的字符集和输入文本的字符集匹配。
- 查看文本: 查看输入文本中是否有在运用字符集时无法映射的字符或符号。
- 指定字符集: 清晰指定字符集,尤其是在不同平台之间传输文本时。最好运用规范字符集,例如UTF-8或ISO-8859-1等。 假如以上解决方法都无效,你或许需求查看代码以确定是否有其他问题。
0x02 解决方案
既然是字符集(文件编码)相关的问题,解决方案有 2 个思路:
- 去掉 Jenkins Job 里脚本和指令中的中文等字符
- 让 Jenkins 的运转环境支撑 UTF-8 编码,以正常处理和展现中文内容
方案一:移除无法正常处理和显现的中文内容
进入 Jenkins Job 的装备中,定位报错的过程卡到哪一个环节,查看脚本和指令是否运用了中文内容(注释也算)。
在我的 Job 装备是 Build Steps - 履行 shell
的 shell 脚本中,对指令做了中文注释,移除调中文内容,保存并重新履行一下 Job 的运转任务,发现能够正常完成构建任务了。
方案二:让 Jenkins 支撑中文
让 Jenkins 正确处理和展现中文,有 2 个方法,能够根据自身状况进行设置:
- 设置机器的 LANG=”C.UTF-8”
- ENKINS_JAVA_OPTS 或许 JAVA_OPTS 的值添加
-Dfile.encoding=UTF8
的内容
这里推荐修正 LANG 的值来支撑中文:
由于我运用 Docker 方法装置的 Jenkins,所以只需求在创立 container 时设置 -e LANG="C.UTF-8"
即可;怎么你运用 portainer 或许 Docker Compose,可自行查找设置、修正环境变量的方法。
对于 ENKINS_JAVA_OPTS 或许 JAVA_OPTS 的值添加 -Dfile.encoding=UTF8
的内容:
注意一点,ENKINS_JAVA_OPTS 只影响 Jenkins 程序;JAVA_OPTS 则会影响一切本机器下一切根据 Java 运转的程序。 至于修正方法,参考上面修正 LANG 的过程。
最终,对修正是否收效进行查看:
设置结束并重启 Jenkins 后,假如你是管理员,进入 Dashboard-体系管理-体系信息-环境变量
查看下当前 Jenkins 的环境变量:
- 查看 LANG 的值,查看下是否为 C.UTF-8 ;
- 或许,查看 JENKINS_JAVA_OPTS 或许 JAVA_OPTS 的值里是否有
-Dfile.encoding=UTF8
; - 最终,运转一下之前 Job 的构建任务,看看能否正常显现中文和正常完成构建。
其他方案
网上也有一些其他方案,假如报错信息中没有 java.nio.charset.UnmappableCharacterException: Input length = 1
的信息,或许就不是编码问题。能够测验:
- 重启 Jenkins
- 或许磁盘空间缺乏,可测验删去
/tmp/
缓存目录下的文件 - 或许目录权限不正确,测验把 Job 的 workspace 地点目录修正为 jenkins 能够读写的用户权限
0x03 总结
定位问题的过程中,首要检索报错信息中的 Unable to produce a script file,有许多材料都没有阐明为什么要运用文章里的解决方案,仅仅是做个记载,没有深化追溯原因,走了不少弯路。
之后,结合 Commit 信息乱码,检索报错信息中的 java.nio.charset.UnmappableCharacterException: Input length = 1,终于找到中心原因:文件编码问题。之后一路查官方文档等,找到了适宜的解决方案。
材料:
- Jenkins 的 Docker 装置文档
- Jenkins 装置文档
假如有什么主张或许问题能够随时联系我,一起讨论学习:
- Github: likfe
- CSDN:他叫自己Mr.张
- :cafeting
- 微博:cafeting
本文正在参与「金石计划」