{"id":17643458,"url":"https://github.com/hymkor/expect","last_synced_at":"2025-07-19T03:03:31.238Z","repository":{"id":42238046,"uuid":"94399352","full_name":"hymkor/expect","owner":"hymkor","description":"Expect-lua for Windows ( A text-terminal automation tool similar to expect(1) using Lua )","archived":false,"fork":false,"pushed_at":"2024-12-04T04:11:36.000Z","size":127,"stargazers_count":124,"open_issues_count":0,"forks_count":16,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-05-25T09:06:57.794Z","etag":null,"topics":["commandprompt","go","golang","golang-application","golang-tools","gopher-lua","lua","windows"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hymkor.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-06-15T04:22:46.000Z","updated_at":"2025-05-06T06:07:00.000Z","dependencies_parsed_at":"2024-06-18T22:45:46.650Z","dependency_job_id":"fda0279d-c6d2-4a96-9d9e-b706612ab0d4","html_url":"https://github.com/hymkor/expect","commit_stats":{"total_commits":222,"total_committers":3,"mean_commits":74.0,"dds":"0.013513513513513487","last_synced_commit":"c074868e4f1a22b64495a5b9019bf02655549769"},"previous_names":["zetamatta/expect"],"tags_count":33,"template":false,"template_full_name":null,"purl":"pkg:github/hymkor/expect","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hymkor%2Fexpect","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hymkor%2Fexpect/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hymkor%2Fexpect/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hymkor%2Fexpect/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hymkor","download_url":"https://codeload.github.com/hymkor/expect/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hymkor%2Fexpect/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265878763,"owners_count":23843010,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["commandprompt","go","golang","golang-application","golang-tools","gopher-lua","lua","windows"],"created_at":"2024-10-23T09:04:47.888Z","updated_at":"2025-07-19T03:03:31.216Z","avatar_url":"https://github.com/hymkor.png","language":"Go","readme":"[![Go Report Card](https://goreportcard.com/badge/github.com/hymkor/expect)](https://goreportcard.com/report/github.com/hymkor/expect)\r\n\r\nExpect-lua for Windows\r\n======================\r\n\r\n- A tool like `expect` on Linux.\r\n- The syntax of scripts is exactly same with Lua 5.1 except for some functions.\r\n    - The reference manuals of Lua 5.1 exist in the Lua official site.  \r\n        Please see [https://www.lua.org/docs.html](https://www.lua.org/docs.html)\r\n    - Expect-lua uses [GopherLua](https://github.com/yuin/gopher-lua) as the VM for Lua.\r\n- These functions are extended in Expect-lua\r\n    - `RC=expect(A,B,C...)` accesses CONOUT$ directly and watches the cursor-line and abobe N-lines (N+1 can be set by `capturelines`:default is 2) (0.1 seconds interval)\r\n        - When A was found in cursor-line, RC=0\r\n        - When B was found in cursor-line, RC=1\r\n        - When C was found in cursor-line, RC=2\r\n        - :\r\n        - When error occured, RC=-1\r\n        - When timeout occurs, RC=-2 (set variable like `timeout=(SECONDS)`,default 1 hour)\r\n        - When RC \u0026gt;= 0, these global variables are set.\r\n            - `_MATCH` - The string matched.\r\n            - `_MATCHPOSITION` - The position where matched.\r\n            - `_MATCHLINE` - The matched whole line.\r\n            - `_PREMATCH` - The string preceding matched.\r\n            - `_POSTMATCH` - The string following matched.\r\n    - `send(TEXT)` sends TEXT to the terminal as keyboard events.\r\n        - `send(TEXT,MS)` waits MS [m-seconds] per 1-character (for plink.exe)\r\n    - `sendvkey(VIRTUAL_KEYCODE)` sends [a virtual key code](https://learn.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes)\r\n    - `sendln()` is same as send() but append CR.\r\n    - `PID=spawn(NAME,ARG1,ARG2,...)` starts applications and\r\n        - On success, `PID` is process-id(integer).\r\n        - On failure, `PID` is nil.\r\n    - `echo()` controls echoback\r\n        - `echo(true)`: echo on\r\n        - `echo(false)`: echo off\r\n        - `echo(\"...\")`: print a string\r\n    - `arg[]` contains commandline arguments (`arg[0]` is scriptname)\r\n    - `kill(PROCESS-ID)` kills the process. (since v0.4.0)\r\n    - `spawnctx(NAME,ARG1,ARG2,...)` is similar with spawn() but the process started by spawnctx is killed automatically when Ctrl-C is pressed. (since v0.5.0)\r\n    - `wait(PID)` waits the process of PID terminates.\r\n    - `shot(N)` reads N-lines from the console buffer and returns them. (since v0.8.0)\r\n    - `sleep(N)` sleeps N-seconds. (since v0.9.0)\r\n    - `usleep(MICROSECOND)` sleep N-micrseconds. (since v0.9.0)\r\n    - `local OBJ=create_object()` creates OLE-Object (since v0.10.0)\r\n        - `OBJ:method(...)` calls method\r\n        - `OBJ:_get(\"PROPERTY\")` returns the value of the property.\r\n        - `OBJ:_set(\"PROPERTY\",value)` sets the value to the property.\r\n        - `OBJ:_iter()` returns an enumerator of the collection.\r\n        - `OBJ:_release()` releases the COM-instance.\r\n        - `local N=to_ole_integer(10)` creates the integer value for OLE.\r\n\r\n``` lua\r\nlocal screen = assert(shot(25))\r\nfor i = 1,#screen do\r\n    print( i,screen[i] )\r\nend\r\n```\r\n\r\nInstall\r\n-------\r\n\r\nDownload the binary package from [Releases](https://github.com/hymkor/expect/releases) and extract the executable.\r\n\r\n### via go install\r\n\r\n```\r\ngo install github.com/hymkor/expect@latest\r\n```\r\n\r\n### via scoop-installer\r\n\r\n```\r\nscoop install https://raw.githubusercontent.com/hymkor/expect/master/expect-lua.json\r\n```\r\n\r\nor\r\n\r\n```\r\nscoop bucket add hymkor https://github.com/hymkor/scoop-bucket\r\nscoop install expect-lua\r\n```\r\n\r\nSample\r\n------\r\n\r\nsample.lua:\r\n\r\n``` lua\r\nif #arg \u003c 2 then\r\n    print(\"expect.exe sample.lua USERNAME@DOMAIN PASSWD\")\r\n    os.exit(0)\r\nend\r\nlocal account = arg[1]\r\nlocal password = arg[2]\r\nlocal sshexe = os.getenv(\"windir\") .. \"\\\\System32\\\\OpenSSH\\\\ssh.exe\"\r\n\r\nlocal sshpid = spawn(sshexe,\"-p\",\"22\",account)\r\nif not sshpid then\r\n    print(\"ssh.exe is not found\")\r\n    os.exit(1)\r\nend\r\ntimeout = 10\r\ncapturelines = 3 -- default is 2\r\nlocal promptkeyword = \"$\"\r\n\r\nwhile true do\r\n    local rc = expect(\r\n    \"password:\",\r\n    \"Are you sure you want to continue connecting (yes/no/[fingerprint])?\",\r\n    \"Could not resolve hostname\")\r\n\r\n    if rc == 0 then\r\n        sendln(password)\r\n        sleep(1)\r\n        rc = expect(promptkeyword,\"Permission denied, please try again\")\r\n        if rc == 0 then\r\n            sleep(1)\r\n            sendln(\"exit\")\r\n            sleep(1)\r\n            echo()\r\n            echo(\"-- This is the sample script\")\r\n            echo(\"-- Write your code to do in your server instead of sendln(\\\"exit\\\")\")\r\n        else\r\n            print()\r\n            echo(string.format(\r\n            \"-- The expected prompt keyword(%s) was not found.\",\r\n            promptkeyword))\r\n\r\n            -- kill(sshpid)\r\n        end\r\n        break\r\n    elseif rc == 1 then\r\n        sendln(\"yes\")\r\n        print() -- move cursor down not to capture same keyword\r\n    elseif rc == -2 then\r\n        echo(\"TIMEOUT\")\r\n        break\r\n    elseif rc == -1 then\r\n        echo(\"ERROR\")\r\n        break\r\n    else\r\n        echo(string.format(\"Error keyword found \\\"%s\\\". Exit\",_MATCH))\r\n        break\r\n    end\r\nend\r\n```\r\n\r\nOn the command prompt:\r\n\r\n```console\r\n$ .\\expect sample.lua example@example.com PASSW0RD\r\nExpect-lua v0.10.0-3-ga2986b0-windows-amd64\r\nexample@example.com's password:\r\nLast login: Mon Dec 26 23:18:11 2022 from XXXXXXXX-XXXXX.XXXX.XX.XXX.XXX.XXX.XX.XX\r\nFreeBSD 9.1-RELEASE-p24 (XXXXXXXX) #0: Thu Feb  5 10:03:29 JST 2015\r\n\r\nWelcome to FreeBSD!\r\n\r\n[example@XXXXXXX ~]$ exit\r\nlogout\r\nConnection to example.com closed.\r\n-- This is the sample script\r\n-- Write your code to do in your server instead of sendln(\"exit\")\r\n```\r\n\r\nThe script embedded in the batchfile:\r\n\r\n```sample.cmd\r\n@expect.exe \"%~f0\"\r\n@exit /b\r\n\r\n-- Lines starting with '@' are replaced to '--@' by expect.exe\r\n-- to embed the script into the batchfile.\r\n\r\necho(true)\r\nif spawn([[c:\\Program Files\\Git\\usr\\bin\\ssh.exe]],\"foo@example.com\") then\r\n    expect(\"password:\")\r\n    echo(false)\r\n    send(\"PASSWORD\\r\")\r\n    expect(\"~]$\")\r\n    echo(true)\r\n    send(\"exit\\r\")\r\nend\r\n```\r\n\r\nFAQ\r\n---\r\n\r\n### `expect sample.lua \u003e log` does not work.\r\n\r\nExpect-lua directly accesses the terminal device linked to STDOUT\r\nor STDERR to retrieve the printed text.\r\nTherefore, if the STDOUT/STDERR is redirected to something other\r\nthan the terminal, the screen data of the terminal cannot be\r\naccessed, resulting in an error.\r\nThis is difficult to solve, and it is currently impossible to work\r\nwith redirects.\r\n\r\nIt was ideal that like \"expect\" on Linux, Expect-lua got the stdout\r\nand stderr of the child process via a pipeline,\r\nand then re-output them to the original destination after parsing .\r\nHowever, it is unavailable because on Windows the output is suppressed\r\nuntil CRLF is found when the destination is not the terminal and the expect function can never get a prompt without a newline.\r\n\r\n---\r\n\r\nLooking for a new option? Check out [Lispect](https://github.com/hymkor/lispect)\r\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhymkor%2Fexpect","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhymkor%2Fexpect","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhymkor%2Fexpect/lists"}