I've got a bunch of Macs that have just updated Xcode and need to have the EULA agreement accepted. I'm trying to do this through a script.
#!/usr/bin/expect
set timeout 15
spawn sudo xcodebuild -license
expect {
"*License.rtf'\n" { # Press Enter to view agreement
send "\r"
}
timeout {
send_user "\nFailed\n";
exit 1
}
}
expect {
"Software License Agreements Press 'space' for more, or 'q' for quit" {
send_user " ";
exp_continue;
}
"By typing 'agree' you are agreeing" {
send_user "agree\r"
}
timeout {
send_user "\nTimeout 2\n";
exit 1
}
}
However, it never gets passed the first expect (that is, it never sends the "\r" for 'Enter'.
Here is the output:
$ ./test.sh
spawn sudo xcodebuild -license
You have not agreed to the Xcode license agreements. You must agree to both license agreements below in order to use Xcode.
Hit the Enter key to view the license agreements at '/Applications/Xcode.app/Contents/Resources/English.lproj/License.rtf'
Failed
EDIT: Updated script as follows, now hits timeout at the second expect:
#!/usr/bin/expect
set timeout 15
spawn sudo xcodebuild -license
expect {
"*License.rtf" {
send "\r"
}
timeout {
send_user "\nFailed\n";
exit 1
}
}
expect {
"By typing 'agree' you are agreeing" {
send "agree\r"
}
"*Press 'space' for more, or 'q' for quit" {
send " ";
exp_continue;
}
timeout {
send_user "\nTimeout 2\n";
exit 1
}
}
This kind of ignores the initial topic of using 'except' to scroll through the agreement, but you can also agree to the license with a one liner.
/Applications/Xcode.app/Contents/Developer/usr/bin/xcodebuild -license accept
This always seems to work for me.
This is the script that finally worked for me
#!/usr/bin/expect
set timeout 5
spawn sudo xcodebuild -license
send "\r"
expect {
"By typing 'agree' you are agreeing" {
send "agree\r\n"
}
"Software License Agreements Press 'space' for more, or 'q' to quit" {
send " ";
exp_continue;
}
timeout {
send_user "\nTimeout 2\n";
exit 1
}
}
expect {
timeout {
send_user "\nFailed\n";
exit 1
}
}
For posterity, as this is still unanswered
What I ended up using, which worked for me (but may not be the cleanest):
!/usr/bin/expect
set timeout 5
spawn sudo xcodebuild -license
expect {
"By typing 'agree' you are agreeing" {
send "agree\r\n"
}
"Software License Agreements Press 'space' for more, or 'q' to quit" {
send " ";
exp_continue;
}
timeout {
send_user "\nTimeout 2\n";
exit 1
}
}
expect {
timeout {
send_user "\nFailed\n";
exit 1
}
}
How I came to this conclusion:
I debugged by calling expect -d at the top, like so:
!/usr/bin/expect -d
Once I figured out that it was looking for "agree", instead of "space", I reversed the order and removed the "-d".
I'd be happy to get any other pointers as this is my first time playing around with expect, and I'm pretty impressed with the tool!
Using the information from @Glenn Jackman, I was able to solve this. Here is my solution, embedded in a bash script
/usr/bin/expect<<EOF
spawn sudo xcodebuild -license
expect {
"*License.rtf" {
send "\r";
}
timeout {
send_user "\nExpect failed first expect\n";
exit 1;
}
}
expect {
"*By typing 'agree' you are agreeing" {
send "agree\r";
send_error "\nUser agreed to EULA\n";
}
"*Press 'space' for more, or 'q' to quit*" {
send "q";
exp_continue;
}
timeout {
send_error "\nExpect failed second expect\n";
exit 1;
}
}
EOF
This works for me to accept Mac OSX Xcode license. It is almost identical, just adding bash shell line and ensuring eod markers for expect section. I learned about how to call expect at How to have Expect script output to file .
#!/bin/bash
echo "TOP: Now start expecting things"
/usr/bin/expect -f - <<EOD
set timeout 5
spawn sudo xcodebuild -license
send "\r"
expect {
"By typing 'agree' you are agreeing" {
send "agree\r\n"
}
"Software License Agreements Press 'space' for more, or 'q' to quit" {
send " ";
exp_continue;
}
timeout {
send_user "\nTimeout 2\n";
exit 1
}
}
expect {
timeout {
send_user "\nFailed\n";
exit 1
}
}
EOD