确定Jenkins管道正在运行的当前操作系统的方法是什么?
背景信息:我正在构建一个应该在所有平台(Windows,OSX,linux)上运行的共享Jenkins管道脚本,并在每个平台上执行不同的操作。
我尝试过类似的事情:
import org.apache.commons.lang.SystemUtils
if (SystemUtils.IS_OS_WINDOWS){
bat("Command")
}
if (SystemUtils.IS_OS_MAC){
sh("Command")
}
if (SystemUtils.IS_OS_LINUX){
sh("Command")
}
但即使它在Windows或Mac node
上运行,它也总是进入SystemUtils.IS_OS_LINUX
分支
我试过像这样的快速管道。
node('windows ') {
println ('## OS ' + System.properties['os.name'])
}
node('osx ') {
println ('## OS ' + System.properties['os.name'])
}
node('linux') {
println ('## OS ' + System.properties['os.name'])
}
每个节点都在具有正确操作系统的计算机中正确运行,但所有节点都打印## OS Linux
任何想法?
由于 FEDE
答案 0 :(得分:10)
假设您将Windows作为唯一的非Unix平台,则可以使用管道函数isUnix()
和uname
来检查您所使用的Unix OS:
def checkOs(){
if (isUnix()) {
def uname = sh script: 'uname', returnStdout: true
if (uname.startsWith("Darwin")) {
return "Macos"
}
// Optionally add 'else if' for other Unix OS
else {
return "Linux"
}
}
else {
return "Windows"
}
}
答案 1 :(得分:9)
据我所知,Jenkins只区分windows和unix,即如果在windows上,使用bat,在unix / mac / linux上使用sh。因此,您可以使用isUnix()
,more info here来确定您是在unix还是windows上,并且在unix的情况下使用sh和@Spencer Malone的答案来提供有关该系统的更多信息(如果需要) )。
答案 2 :(得分:2)
我最初使用@fedterzi答案,但发现它有问题,因为它导致了以下崩溃:
org.jenkinsci.plugins.workflow.steps.MissingContextVariableException: Required context class hudson.Launcher is missing
尝试在管道外部调用isUnix()
时(例如,分配变量)。我通过依靠传统的Java方法来确定Os来解决:
def getOs(){
String osname = System.getProperty('os.name');
if (osname.startsWith('Windows'))
return 'windows';
else if (osname.startsWith('Mac'))
return 'macosx';
else if (osname.contains('nux'))
return 'linux';
else
throw new Exception("Unsupported os: ${osname}");
}
这允许在任何管道上下文中调用该函数。
答案 3 :(得分:0)
使用Java类可能不是最好的方法。我很确定除非它是一个jenkins / groovy插件,否则那些在主Jenkins JVM线程上运行。我会研究一种shell方法,例如这里概述的方法:https://stackoverflow.com/a/8597411/5505255
您可以将该脚本包装在shell步骤中以获取stdout,如下所示:
def osName = sh(script: './detectOS', returnStdout: true)
调用上面概述的脚本副本。然后让该脚本返回您想要的操作系统名称,并根据osName var。
返回分支逻辑答案 4 :(得分:0)
我找到的解决方法是
try{
sh(script: myScript, returnStdout: true)
}catch(Exception ex) {
//assume we are on windows
bat(script: myScript, returnStdout: true)
}
或者使用try/catch
而不使用env.NODE_LABELS
的更优雅的解决方案是使用def isOnWindows(){
def os = "windows"
def List nodeLabels = NODE_LABELS.split()
for (i = 0; i <nodeLabels.size(); i++)
{
if (nodeLabels[i]==os){
return true
}
}
return false
}
。假设你已经正确标记了所有节点,你可以写一个像这样的函数
if (isOnWindows()) {
def osName = bat(script: command, returnStdout: true)
} else {
def osName = sh(script: command, returnStdout: true)
}
然后
{{1}}