{"id":13937283,"url":"https://github.com/fgimian/paramiko-expect","last_synced_at":"2025-07-19T23:31:23.971Z","repository":{"id":3514176,"uuid":"4571984","full_name":"fgimian/paramiko-expect","owner":"fgimian","description":"A Python expect-like extension for the Paramiko SSH library which also supports tailing logs.","archived":false,"fork":false,"pushed_at":"2024-06-19T10:42:27.000Z","size":124,"stargazers_count":204,"open_issues_count":34,"forks_count":78,"subscribers_count":13,"default_branch":"master","last_synced_at":"2024-09-19T21:17:46.684Z","etag":null,"topics":["expect","ssh"],"latest_commit_sha":null,"homepage":"","language":"Python","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/fgimian.png","metadata":{"files":{"readme":"README.rst","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":"2012-06-06T12:00:00.000Z","updated_at":"2024-09-12T05:34:04.000Z","dependencies_parsed_at":"2024-05-02T23:03:44.902Z","dependency_job_id":"4adecb78-4d3c-4ee4-8399-0000c48b095e","html_url":"https://github.com/fgimian/paramiko-expect","commit_stats":{"total_commits":86,"total_committers":14,"mean_commits":6.142857142857143,"dds":0.6395348837209303,"last_synced_commit":"597297d63adfa610e3e9c3d7439fd4209b4218de"},"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fgimian%2Fparamiko-expect","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fgimian%2Fparamiko-expect/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fgimian%2Fparamiko-expect/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fgimian%2Fparamiko-expect/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fgimian","download_url":"https://codeload.github.com/fgimian/paramiko-expect/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":226693903,"owners_count":17667757,"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":["expect","ssh"],"created_at":"2024-08-07T23:03:27.824Z","updated_at":"2025-07-19T23:31:23.952Z","avatar_url":"https://github.com/fgimian.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"Paramiko Expect\n===============\n\n.. image:: https://img.shields.io/pypi/l/paramiko-expect.svg\n   :target: https://github.com/fgimian/paramiko-expect/blob/master/LICENSE\n\n.. image:: https://codecov.io/gh/fgimian/paramiko-expect/branch/master/graph/badge.svg\n   :target: https://codecov.io/gh/fgimian/paramiko-expect\n\n.. image:: https://img.shields.io/travis/fgimian/paramiko-expect.svg\n   :target: https://travis-ci.org/fruch/paramiko-expect/\n\n.. image:: https://img.shields.io/pypi/v/paramiko-expect.svg\n   :target: https://pypi.python.org/pypi/paramiko-expect/\n\n.. image:: https://img.shields.io/pypi/pyversions/paramiko-expect.svg\n   :target:  https://pypi.python.org/pypi/paramiko-expect/\n\n.. image:: https://raw.githubusercontent.com/fgimian/paramiko-expect/master/images/paramiko-expect-logo.png\n   :alt: Paramiko Expect Logo\n\nArtwork courtesy of `Open Clip Art\nLibrary \u003chttps://openclipart.org/detail/174780/openmouthed-robot\u003e`_\n\nRepository Archived\n------------\n\nThis project originally started as a POC while I was automating some tasks on Cisco CDS devices\nin my operations role. While the library worked well, I didn't actually get to use it much myself\nas I moved onto an engineering role soon after. Since then,\n`Israel Fruchter \u003chttps://github.com/fruch\u003e`_ has been kindly leading maintenance of the project.\n\nUnfortunately, `Israel is also no longer using this project \u003chttps://github.com/fgimian/paramiko-expect/issues/96#issuecomment-2132608755\u003e`_\nand `no suitable maintainers were found to take over \u003chttps://github.com/fgimian/paramiko-expect/issues/97\u003e`_.\n\nAs such, I have decided to archive the project and officially call it discontinued. The community\nis welcome to fork the project and continue its development if required.\n\nIntroduction\n------------\n\nParamiko Expect provides an expect-like extension for the Paramiko SSH library\nwhich allows scripts to fully interact with hosts via a true SSH\nconnection.\n\nThe class is constructed with an SSH Client object (this will likely be\nextended to support a transport in future for more flexibility).\n\nQuick Start\n-----------\n\nTo install paramiko-expect, simply run the following at your prompt:\n\n.. code:: bash\n\n    # from pypi\n    pip install paramiko-expect\n\n    # from source\n    pip install git+https://github.com/fgimian/paramiko-expect.git\n\nSo let's check out how it works in general (please see\n`paramiko_expect-demo.py \u003chttps://github.com/fgimian/paramiko-expect/blob/master/examples/paramiko_expect-demo.py\u003e`_\nfor the complete code):\n\n.. code:: python\n\n    # Connect to the host\n    client.connect(hostname=hostname, username=username, password=password)\n\n    # Create a client interaction class which will interact with the host\n    interact = SSHClientInteraction(client, timeout=10, display=True)\n    interact.expect(prompt)\n\n    # Run the first command and capture the cleaned output, if you want the output\n    # without cleaning, simply grab current_output instead.\n    interact.send('uname -a')\n    interact.expect(prompt)\n    cmd_output_uname = interact.current_output_clean\n\n    # Now let's do the same for the ls command but also set a timeout for this\n    # specific expect (overriding the default timeout)\n    interact.send('ls -l /')\n    interact.expect(prompt, timeout=5)\n    cmd_output_ls = interact.current_output_clean\n\n    # To expect multiple expressions, just use a list.  You can also selectively\n    # take action based on what was matched.\n\n    # Method 1: You may use the last_match property to find out what was matched\n    interact.send('~/paramiko_expect-demo-helper.py')\n    interact.expect([prompt, 'Please enter your name: '])\n    if interact.last_match == 'Please enter your name: ':\n        interact.send('Fotis Gimian')\n        interact.expect(prompt)\n\n    # Method 2: You may use the matched index to determine the last match (like pexpect)\n    interact.send('~/paramiko_expect-demo-helper.py')\n    found_index = interact.expect([prompt, 'Please enter your name: '])\n    if found_index == 1:\n        interact.send('Fotis Gimian')\n        interact.expect(prompt)\n\n    # Send the exit command and expect EOF (a closed session)\n    interact.send('exit')\n    interact.expect()\n\n    # Print the output of each command\n    print '-'*79\n    print 'Cleaned Command Output'\n    print '-'*79\n    print 'uname -a output:'\n    print cmd_output_uname\n    print 'ls -l / output:'\n    print cmd_output_ls\n\n**Important**: Before running this script, be sure to place\n`paramiko_expect-demo-helper.py \u003chttps://github.com/fgimian/paramiko-expect/blob/master/examples/paramiko_expect-demo-helper.py\u003e`_\nin ``~``.\n\nThe print statements at the bottom of the script provide the following\noutput:\n\n.. code:: bash\n\n    -------------------------------------------------------------------------------\n    Cleaned Command Output\n    -------------------------------------------------------------------------------\n    uname -a output:\n    Linux fotsies-ubuntu-testlab 3.2.0-23-generic #36-Ubuntu SMP Tue Apr 10 20:39:51 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux\n\n    ls -l / output:\n    total 77\n    drwxr-xr-x  2 root root  4096 May  1 22:21 bin\n    drwxr-xr-x  4 root root  1024 May  1 22:22 boot\n    drwxr-xr-x 15 root root  4300 Jun 12 15:00 dev\n    drwxr-xr-x 90 root root  4096 Jun 12 16:45 etc\n    drwxr-xr-x  4 root root  4096 May  1 23:37 home\n    lrwxrwxrwx  1 root root    33 May  1 22:18 initrd.img -\u003e /boot/initrd.img-3.2.0-23-generic\n    drwxr-xr-x 18 root root  4096 May  1 22:21 lib\n    drwxr-xr-x  2 root root  4096 May  1 22:17 lib64\n    drwx------  2 root root 16384 May  1 22:17 lost+found\n    drwxr-xr-x  4 root root  4096 May  1 22:18 media\n    drwxr-xr-x  2 root root  4096 Apr 19 19:32 mnt\n    drwxr-xr-x  2 root root  4096 May  1 22:17 opt\n    dr-xr-xr-x 84 root root     0 Jun 12 15:00 proc\n    drwx------  3 root root  4096 May 30 23:32 root\n    drwxr-xr-x 15 root root   560 Jun 12 17:02 run\n    drwxr-xr-x  2 root root  4096 Jun  4 20:59 sbin\n    drwxr-xr-x  2 root root  4096 Mar  6 04:54 selinux\n    drwxr-xr-x  2 root root  4096 May  1 22:17 srv\n    drwxr-xr-x 13 root root     0 Jun 12 15:00 sys\n    drwxrwxrwt  2 root root  4096 Jun 12 16:17 tmp\n    drwxr-xr-x 10 root root  4096 May  1 22:17 usr\n    drwxr-xr-x 12 root root  4096 Jun 12 13:16 var\n    lrwxrwxrwx  1 root root    29 May  1 22:18 vmlinuz -\u003e boot/vmlinuz-3.2.0-23-generic\n\nFor interacting with tail-like scripts, we can use the tail function (please see\n`paramiko_expect-tail-demo.py \u003chttps://github.com/fgimian/paramiko-expect/blob/master/examples/paramiko_expect-tail-demo.py\u003e`_\nfor the complete code):\n\n.. code:: python\n\n    # Connect to the host\n    client.connect(hostname=hostname, username=username, password=password)\n\n    # Create a client interaction class which will interact with the host\n    interact = SSHClientInteraction(client, timeout=10, display=False)\n    interact.expect(prompt)\n\n    # Send the tail command\n    interact.send('tail -f /var/log/auth.log')\n\n    # Now let the class tail the file for us\n    interact.tail(line_prefix=hostname+': ')\n\nThe true power of the tail function will become more apparent when you\ncheck out the `Multi-SSH \u003chttps://github.com/fgimian/multissh\u003e`_\nlibrary. Ever thought about tailing a log on multiple servers? Well\ndream no more my friend, it's here!\n\n\nTests\n-----\n\nNot full coverage yet, and assumes you have docker setup:\n\n.. code:: bash\n\n    pip install -r requirements-test.txt\n    docker run -d -p 2222:22 -v `pwd`/examples:/examples -v `pwd`/test/id_rsa.pub:/root/.ssh/authorized_keys  docker.io/panubo/sshd\n    pytest -s --cov paramiko_expect --cov-report term-missing\n\n\nContributions\n-------------\n\n- Israel Fruchter (@fruch) - Tests / CI / Uploads to Pypi\n- Kiseok Kim (@kiseok7) - Vagrent image\n\n\nLicense\n-------\n\nParamiko Expect is released under the **MIT** license. Please see the\n`LICENSE \u003chttps://github.com/fgimian/paramiko-expect/blob/master/LICENSE\u003e`_\nfile for more details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffgimian%2Fparamiko-expect","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffgimian%2Fparamiko-expect","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffgimian%2Fparamiko-expect/lists"}