{{위키데이터 속성 추적}}
{{소프트웨어 정보
| name                   = Expect
| author                 = [[Don Libes]]
| developer              = 닐스 칼슨(Nils Carlson)
| latest release version = 5.45.4
| latest release date    = {{시작 날짜와 나이|2018|02|04|df=yes}}
| programming language   = [[Tcl]]
| operating system       = [[POSIX]], [[마이크로소프트 윈도우|윈도우]]
| license                = [[퍼블릭 도메인]]<ref>{{웹 인용 | url=http://expect.sourceforge.net/FAQ.html#q6 | title=Expect FAQ: Our company policy requires a license to use Expect. Where can we get a license? | 확인날짜=2018-04-21 | archive-date=2017-12-01 | archive-url=https://web.archive.org/web/20171201202001/http://expect.sourceforge.net/FAQ.html#q6 | url-status= }}</ref>
| website                = {{URL|http://core.tcl.tk/expect}}
| discontinued = 아니오
}}
'''Expect'''(익스펙트)는 [[Don Libes]]가 개발한 [[Tcl]] 스크립팅 언어의 확장 기능으로서 [[단말기|터미널]] 인터페이스를 노출하는 프로그램과의 상호작용을 자동화하기 위한 프로그램이다. Expect는 원래 1990년 [[유닉스]] 시스템을 위해 개발되었으나 그 뒤로 [[마이크로소프트 윈도우]]와 다른 운영 체제용으로 이용이 가능해졌다.

== 기초 ==
Expect는 [[텔넷]], [[파일 전송 프로토콜]], [[passwd]], [[fsck]], [[rlogin]], [[tip]], [[시큐어 셸|SSH]]와 같은 상호작용 [[응용 소프트웨어|응용 프로그램]]의 제어를 자동화하기 위해 사용된다. Expect는 [[의사 터미널]](유닉스)을 사용하거나 콘솔을 에뮬레이트(윈도우)하고 대상 프로그램을 시작한 다음 마치 인간 세상에서 하는 것처럼 해당 프로그램과 통신하며 이는 터미널이나 콘솔 인터페이스를 통해 이루어진다. 또다른 Tcl 확장 기능인 [[Tk]]는 [[그래픽 사용자 인터페이스]]를 제공하기 위해 사용할 수 있다.

Expect는 [[정규 표현식]] 패턴 매칭과 일반 프로그램 기능들이 있으므로 단순한 스크립트들이 [[프로그래밍 언어]], [[매크로 (컴퓨터 과학)|매크로]], 기타 프로그램 매커니즘이 결여된 텔넷, FTP, SSH 등의 프로그램들을 똑똑하게 제어할 수 있게 한다.

== 사용법 ==
'autoexpect'라는 도구를 사용하여 expect 스크립트의 생성을 자동화할 수 있다. 이 도구는 동작을 관찰하여 휴리스틱을 사용하여 expect를 생성한다. 생성된 코드의 크기가 클 수 있고 다소 아리송할 수 있지만 생성된 스크립트를 트윅하여 정확한 코드를 얻어내는 것이 가능하다.

<syntaxhighlight lang="tcl">
# Assume $remote_server, $my_user_id, $my_password, and $my_command were read in earlier
# in the script.
# Open a telnet session to a remote server, and wait for a username prompt.
spawn telnet $remote_server
expect "username:"
# Send the username, and then wait for a password prompt.
send "$my_user_id\r"
expect "password:"
# Send the password, and then wait for a shell prompt.
send "$my_password\r"
expect "%"
# Send the prebuilt command, and then wait for another shell prompt.
send "$my_command\r"
expect "%"
# Capture the results of the command into a variable. This can be displayed, or written to disk.
set results $expect_out(buffer)
# Exit the telnet session, and wait for a special end-of-file character.
send "exit\r"
expect eof
</syntaxhighlight>

다른 예로 FTP를 자동화하는 스크립트는 다음과 같다:

<syntaxhighlight lang="tcl">
# Set timeout parameter to a proper value.
# For example, the file size is indeed big and the network speed is really one problem,
# you'd better set this parameter a value.
set timeout -1
# Open an ftp session to a remote server, and wait for a username prompt.
spawn ftp $remote_server
expect "username:"
# Send the username, and then wait for a password prompt.
send "$my_user_id\r"
expect "password:"
# Send the password, and then wait for an ftp prompt.
send "$my_password\r"
expect "ftp>"
# Switch to binary mode, and then wait for an ftp prompt.
send "bin\r"
expect "ftp>"
# Turn off prompting.
send "prompt\r"
expect "ftp>"
# Get all the files
send "mget *\r"
expect "ftp>"
# Exit the ftp session, and wait for a special end-of-file character.
send "bye\r"
expect eof
</syntaxhighlight>

아래는 (비밀번호와 함께) SFTP를 자동화하는 예이다:

<syntaxhighlight lang="tcl">
#!/usr/bin/env expect -f

# procedure to attempt connecting; result 0 if OK, 1 otherwise
proc connect {passw} {
  expect {
    "Password:" {
      send "$passw\r"
        expect {
          "sftp*" {
            return 0
          }
        }
    }
  }
  # timed out
  return 1
}

#read the input parameters
set user [lindex $argv 0]
set passw [lindex $argv 1]
set host [lindex $argv 2]
set location [lindex $argv 3]
set file1 [lindex $argv 4]
set file2 [lindex $argv 5]

#puts "Argument data:\n";
#puts "user: $user";
#puts "passw: $passw";
#puts "host: $host";
#puts "location: $location";
#puts "file1: $file1";
#puts "file2: $file2";

#check if all were provided
if { $user == "" || $passw == "" || $host == "" || $location == "" || $file1 == "" || $file2 == "" } {
  puts "Usage: <user> <passw> <host> <location> <file1 to send> <file2 to send>\n"
  exit 1
}

#sftp to specified host and send the files
spawn sftp $user@$host

set rez [connect $passw]
if { $rez == 0 } {
  send "cd $location\r"
  set timeout -1
  send "put $file2\r"
  send "put $file1\r"
  send "ls -l\r"
  send "quit\r"
  expect eof
  exit 0
}
puts "\nError connecting to server: $host, user: $user and password: $passw!\n"
exit 1
</syntaxhighlight>

이 예에서처럼 명령 줄 인수로 비밀번호를 사용하는 것은 커다란 보안 구멍인데, 해당 머신의 다른 사용자가 [[Ps (유닉스)|ps]]를 실행함으로써 이 비밀번호를 읽어낼 수 있다. 그러나 인수로 비밀번호를 지정하지 않고 비밀번호를 직접 물어보게 하는 코드를 추가할 수 있다. 이것이 더 안전한 편이다. 아래의 예를 참고할 것.

<syntaxhighlight lang="tcl">
stty -echo
send_user -- "Enter Password: "
expect_user -re "(.*)\n"
send_user "\n"
stty echo
set PASS $expect_out(1,string)
</syntaxhighlight>

사용자 머신에서 자동화하는 ssh 로그인의 다른 예는 다음과 같다:

<syntaxhighlight lang="tcl">
#timeout is a predefined variable in expect which by default is set to 10 sec
#spawn_id is another default variable in expect.
#It is good practice to close spawn_id handle created by spawn command
set timeout 60
spawn ssh $user@machine
while {1} {
  expect {

    eof                          {break}
    "The authenticity of host"   {send "yes\r"}
    "password:"                  {send "$password\r"}
    "*\]"                        {send "exit\r"}
  }
}
wait
close $spawn_id
</syntaxhighlight>

== 대안 ==
C#, 자바, 스칼라, 그루비, 펄, 파이썬, 루비, 셸, Go와 같은 다른 언어로 된 다양한 프로젝트는 Expect와 같은 기능을 구현한다. 이들은 일반적으로 원래의 Expect의 복제물은 아니지만 유사한 개념의 양상을 보인다.

=== C# ===
* [https://web.archive.org/web/20131224094314/http://blog.iwanek.eu/expect-net/ Expect.NET]&nbsp;— Expect functionality for C# (.NET)
* [https://github.com/CBonnell/dotnetexpect DotNetExpect]&nbsp;— An Expect-inspired console automation library for .NET

=== 자바 ===
* [https://github.com/cverges/expect4j expect4j]&nbsp;— an attempt at a Java clone of the original Expect
* [http://expectj.sourceforge.net/ ExpectJ]&nbsp;— a Java implementation of the Unix expect utility
* [https://github.com/ronniedong/Expect-for-Java Expect-for-Java]&nbsp;— pure Java implementation of the Expect tool
* [https://github.com/iTransformers/expect4java expect4java]&nbsp; - a Java implementation of the Expect tool, but supports nested clousures. There is also wrapper for Groovy language DSL.

=== 스칼라 ===
* [https://github.com/Lasering/scala-expect scala-expect]&nbsp;— a Scala implementation of a very small subset of the Expect tool.

=== 그루비 ===
* [https://github.com/iTransformers/expect4groovy expect4groovy]&nbsp; - a Groovy DSL implementation of Expect tool.

=== 펄 ===
* [http://sourceforge.net/projects/expectperl Expect.pm]&nbsp;— [[펄]] module (newest version at [https://metacpan.org/pod/Expect metacpan.org])

=== 파이썬 ===
* [https://github.com/pexpect/pexpect Pexpect]&nbsp;— [[파이썬]] module for controlling interactive programs in a pseudo-terminal
* [https://pypi.python.org/pypi/winpexpect winpexpect]&nbsp;— port of pexpect to the Windows platform

=== 루비 ===
* [https://web.archive.org/web/20170311165445/http://rubyforge.org/projects/rexpect RExpect]&nbsp;— a drop in replacement for the expect.rb module in the standard library.
* [https://github.com/jesnault/expect4r Expect4r]&nbsp;— Interact with Cisco IOS, IOS-XR, and Juniper JUNOS CLI

=== 셸 ===
* [http://empty.sourceforge.net Empty]&nbsp;— expect-like utility to run interactive commands in the UNIX shell-scripts

=== Go ===
* [https://github.com/google/goexpect GoExpect]&nbsp;- expect-like package for the Go language

== 각주 ==
{{각주}}

== 추가 문헌 ==
* {{서적 인용
 | last = Libes
 | first = Don
 | year = 1995
 | title = Exploring Expect: A Tcl-Based Tool for Automating Interactive Programs
 | url = https://archive.org/details/exploringexpectt00libe
 | publisher = O'Reilly & Associates, Inc
 | isbn = 1-565-92090-2
}}
* "[https://web.archive.org/web/20180408033212/http://www.cotse.com/dlf/man/expect/bulletproof1.htm Advanced Programming in Expect: A Bulletproof Interface]"

== 외부 링크 ==
* {{공식 웹사이트}}
* {{SourceForge|expect}}
* [http://wiki.tcl.tk/201 Expect page] — on The Tcler's Wiki
* [https://www.ibm.com/developerworks/community/blogs/brian/entry/when_to_use_expect_scripting_and_when_to_avoid_it10?lang=en IBM Blog]

[[분류:스크립트 언어]]
[[분류:Tk]]
[[분류:자동화 소프트웨어]]