Search code examples
iosxcodejenkinsgroovyxcrun

get output from xcrun xctrace list devices


On a jenkins pipeline, I execute:

def devicesText = sh(script: "xcrun xctrace list devices", returnStdout: true)
printf devicesText

which has strange behaviour, since it prints the output on the console but does not save the output in the variable. The console looks like this (the ids have been replaced with XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX):

+ xcrun xctrace list devices
== Devices ==
SAM Team - Build Server 2018 (XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)

== Simulators ==
Apple Watch Series 5 - 40mm (7.0) (XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)
Apple Watch Series 5 - 44mm (7.0) (XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)
iPad (7th generation) (13.5) (XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)
iPad Air (3rd generation) (13.5) (XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)
iPad Pro (11-inch) (2nd generation) (13.5) (XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)
iPad Pro (12.9-inch) (4th generation) (13.5) (XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)
iPad Pro (9.7-inch) (13.5) (XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)
iPhone 11 (13.5) (XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)
iPhone 11 Pro (13.5) (XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)
iPhone 11 Pro Max (13.5) (XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)
iPhone 6s (13.5) (XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)
iPhone 8 (13.5) (XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)
iPhone 8 Plus (13.5) (XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)
iPhone SE (2nd generation) (13.5) (XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)
[Pipeline] echo

As you can see the echo is empty since it was not copied to the variable. How can I get the output to be saved in the variable?

(it used to work with the deprecated command instruments -s devices)


Solution

  • Somehow xcrun xctrace prints the output to stderr.

    So in order to get stderr logs in stdout simply redirect them to stdout with 2>&1.

    -> xcrun xctrace list devices 2>&1 | grep -oE 'iPhone.*?[^\(]+' | head -1 | awk '{$1=$1;print}'