Use `expect` to scroll through and accept license agreement

為{幸葍}努か 提交于 2019-12-06 02:44:47

问题


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
    }
}

回答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.




回答2:


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
    }
}



回答3:


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!




回答4:


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



回答5:


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


来源:https://stackoverflow.com/questions/26125036/use-expect-to-scroll-through-and-accept-license-agreement

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!