diff --git a/src/main/java/org/jenkinsci/plugins/durabletask/BourneShellScript.java b/src/main/java/org/jenkinsci/plugins/durabletask/BourneShellScript.java index 1eb947c7..2ece052b 100644 --- a/src/main/java/org/jenkinsci/plugins/durabletask/BourneShellScript.java +++ b/src/main/java/org/jenkinsci/plugins/durabletask/BourneShellScript.java @@ -141,6 +141,8 @@ public String getScript() { ShellController c = new ShellController(ws,(os == OsType.ZOS), cookieValue, jenkinsResultTxtEncoding); FilePath shf = c.getScriptFile(ws); + // JENKINS-70874: if a new process is forked during this call, the writeable file handle will be copied and leading to the "Text file busy" issue + // when executing the script. shf.write(script, scriptEncodingCharset); String shell = null; @@ -229,27 +231,32 @@ private List scriptLauncherCmd(ShellController c, FilePath ws, @CheckFor if (os == OsType.WINDOWS) { // JENKINS-40255 scriptPath = scriptPath.replace("\\", "/"); // cygwin sh understands mixed path (ie : "c:/jenkins/workspace/script.sh" ) } + String scriptPathCopy = scriptPath + ".copy"; // copy file to protect against "Text file busy", see JENKINS-70874 if (capturingOutput) { - cmdString = String.format("{ while [ -d '%s' -a \\! -f '%s' ]; do touch '%s'; sleep 3; done } & jsc=%s; %s=$jsc %s '%s' > '%s' 2> '%s'; echo $? > '%s.tmp'; mv '%s.tmp' '%s'; wait", + cmdString = String.format("cp '%s' '%s'; { while [ -d '%s' -a \\! -f '%s' ]; do touch '%s'; sleep 3; done } & jsc=%s; %s=$jsc %s '%s' > '%s' 2> '%s'; echo $? > '%s.tmp'; mv '%s.tmp' '%s'; wait", + scriptPath, + scriptPathCopy, controlDir, resultFile, logFile, cookieValue, cookieVariable, interpreter, - scriptPath, + scriptPathCopy, c.getOutputFile(ws), logFile, resultFile, resultFile, resultFile); } else { - cmdString = String.format("{ while [ -d '%s' -a \\! -f '%s' ]; do touch '%s'; sleep 3; done } & jsc=%s; %s=$jsc %s '%s' > '%s' 2>&1; echo $? > '%s.tmp'; mv '%s.tmp' '%s'; wait", + cmdString = String.format("cp '%s' '%s'; { while [ -d '%s' -a \\! -f '%s' ]; do touch '%s'; sleep 3; done } & jsc=%s; %s=$jsc %s '%s' > '%s' 2>&1; echo $? > '%s.tmp'; mv '%s.tmp' '%s'; wait", + scriptPath, + scriptPathCopy, controlDir, resultFile, logFile, cookieValue, cookieVariable, interpreter, - scriptPath, + scriptPathCopy, logFile, resultFile, resultFile, resultFile); }