{"id":18062096,"url":"https://github.com/joknarf/thefly","last_synced_at":"2026-03-07T08:05:08.251Z","repository":{"id":257315701,"uuid":"857896895","full_name":"joknarf/thefly","owner":"joknarf","description":"shell teleporter plugin/dotfiles manager (bash/zsh/ksh)","archived":false,"fork":false,"pushed_at":"2026-02-28T16:04:48.000Z","size":202,"stargazers_count":56,"open_issues_count":2,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-28T18:05:21.804Z","etag":null,"topics":["bash","dotfiles-manager","ksh","multihost","multiuser","plugin-manager","shell","shell-environment","ssh","sudo","teleportation","zsh"],"latest_commit_sha":null,"homepage":"https://joknarf.github.io/joknarf-tools","language":"Shell","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/joknarf.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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-09-15T22:10:04.000Z","updated_at":"2026-02-28T17:56:20.000Z","dependencies_parsed_at":"2026-02-28T17:01:01.219Z","dependency_job_id":null,"html_url":"https://github.com/joknarf/thefly","commit_stats":null,"previous_names":["joknarf/thefly"],"tags_count":32,"template":false,"template_full_name":null,"purl":"pkg:github/joknarf/thefly","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joknarf%2Fthefly","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joknarf%2Fthefly/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joknarf%2Fthefly/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joknarf%2Fthefly/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/joknarf","download_url":"https://codeload.github.com/joknarf/thefly/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joknarf%2Fthefly/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30209808,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-07T05:23:27.321Z","status":"ssl_error","status_checked_at":"2026-03-07T05:00:17.256Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["bash","dotfiles-manager","ksh","multihost","multiuser","plugin-manager","shell","shell-environment","ssh","sudo","teleportation","zsh"],"created_at":"2024-10-31T05:05:39.464Z","updated_at":"2026-03-07T08:05:08.242Z","avatar_url":"https://github.com/joknarf.png","language":"Shell","readme":"[![Joknarf Tools](https://img.shields.io/badge/Joknarf%20Tools-Visit-darkgreen?logo=github)](https://joknarf.github.io/joknarf-tools)\n[![Build and Release Packages](https://github.com/joknarf/thefly/actions/workflows/release.yml/badge.svg)](https://github.com/joknarf/thefly/actions/workflows/release.yml)\n[![Shell](https://img.shields.io/badge/shell-bash%20|%20zsh%20|%20ksh%20|%20fish%20-blue.svg)]()\n[![OS](https://img.shields.io/badge/OS-Linux%20|%20macOS%20|%20SunOS%20...-blue.svg)]()\n[![Licence](https://img.shields.io/badge/licence-MIT-blue.svg)](https://shields.io/)\n[![Packages](https://img.shields.io/badge/Packages-%20rpm%20|%20deb%20|%20pkg%20|%20apk%20|%20brew%20-darkgreen.svg)](https://github.com/joknarf/thefly/releases/latest)\n\n# thefly\n\n\u003cimg align=\"left\" width=\"150\" alt=\"flyn2\" src=\"https://github.com/user-attachments/assets/06efbf60-3231-4bf9-82f6-860648d9bf68\" /\u003e\n\n\u003cbr/\u003e\nbash/zsh/ksh/fish plugin/dotfiles manager and teleporter  \n\nYour shell env and plugins are available everywhere (hosts/users)  \n\nbzzz bzzz !  \n\n\u003cbr/\u003e  \n\nWhat's the point to have a fine tuned local shell environment if you lose it as soon as you connect to another server / sudo to another user ?\n\n## Demo\n\n![thefly_bzz](https://github.com/user-attachments/assets/1617632b-db08-40d4-a845-841e8ee5c7c6)\n\n## features\n\nKeep your full shell environment anywhere you go.\n\n* supports bash / zsh / ksh / fish (on Linux / MacOS / ...)\n* multi-shell plugin manager to install / update / uninstall shell plugins\n* multi-shell dotfiles manager\n* teleport dotfiles and plugins through sudo (`flyas`)\n* teleport dotfiles and plugins through ssh (`flyto`)\n* force specific destination shell when sudo or ssh (not using target user shell)\n* create a single pak env file including dotfiles and plugins to be used anywhere (`flypack \u003epak`, `. ./pak`)\n  \n## Install\n\n```\n. \u003c(curl https://raw.githubusercontent.com/joknarf/thefly/main/thefly) install\n```\nor\n```\ngit clone https://github.com/joknarf/thefly\n. thefly/thefly install\n```\nCreates `~/.fly.d/fly` and activate thefly manager for current user\n\nunder `fish` do not source, execute `thefly install` then `. ~/.fly.d/fly.fish activate`\n\nor use your prefered method according to your OS:\n\n```\nbrew install joknarf/tools/thefly\n```\n\n```\nsudo dnf install https://github.com/joknarf/thefly/releases/latest/download/thefly.rpm\n```\n\n```\ncurl -OL https://github.com/joknarf/thefly/releases/latest/download/thefly.deb\nsudo dpkg -i thefly.deb\n```\n\n```\ncurl -OL https://github.com/joknarf/thefly/releases/latest/download/thefly.apk\nsudo apk add --allow-untrusted thefly.apk\n```\n\n```\ncurl -OL https://github.com/joknarf/thefly/releases/latest/download/thefly.pkg\nsudo installer -pkg thefly.pkg -target /\n```\n\nthen run:\n```\nthefly install\n. ~/.fly.d/fly activate\n```\n\nAdd in your rc file (.profile .bash_profile .bashrc .zshrc):\n```\n. ~/.fly.d/fly source\n```\nfor `fish` add in your `.config/fish/config.fish`:\n```\n. ~/.fly.d/fly.fish source\n```\nGet some help\n```\nfly help\n```\n## Plugins management\n\n* add plugin\n```\nfly add joknarf/redo\n```\nclones `https://github.com/joknarf/redo` in `~/.fly.d/plugins/redo` and sources the `plugin.\u003cshell\u003e`  \n\n(all plugins in `~/fly.d/plugins/*/*.plugin.\u003cshell\u003e` will be sourced at login with `fly source` in your shell rc file)\n\n* update plugin\n```\nfly update [plugin]\n```\n\n* remove plugin\n```\nfly del [plugin]\n```\n\n* update user fly\n```\nfly upgrade\n```\n\n## Teleport plugins/shell env\n\nthefly is able to duplicate your .fly.d directory through sudo and ssh to login with your full environment.\n\nWhen teleporting the .fly.d is duplicated (without cvs files/tests) in :\n```\n/tmp/.fly.$USER/\u003cid\u003e/.fly.d\n```\nfiles are owned by target user, `$FLY_HOME` is set to `/tmp/.fly.$USER/\u003cid\u003e`\n\nYou can use all teleport method multiple times (`flyto host` then `flyas user`...)\n\n### To another user\n\nsudo login interactive shell to another user with your env\n(current user need to have sudo privilege to target user)\n\n```\n$ flyas \u003cuser\u003e [shell]\nor\n$ fsu \u003cuser\u003e [shell]\n```\nBy default uses `\u003cuser\u003e`'s shell.\n\n### To another host\n\nssh connect with interactive shell to another host with your env\n```\n$ flyto [\u003cssh opts\u003e] \u003cuser\u003e[\u003c@host\u003e]\nor\n$ fssh [\u003cssh opts\u003e] \u003cuser\u003e[\u003c@host\u003e]\n```\n\nby default uses `\u003cuser\u003e` shell, to force your favorite shell use `fsshb` (bash) - `fsshz` (zsh) - `fsshk` (ksh)\n\n### To another shell\n\nChange current shell and load your env/plugins :  \n```\n$ flysh \u003cshell\u003e # shell in bash ksh zsh\n```\nor `fbash` - `fzsh` - `fksh`  \n \n## Customize env\n\n* You can use `FLY_TMPDIR` variable to set the teleportation destination directory instead of default `/tmp` (/tmp could be mounted as noexec, or being full...):\n\n```\nFLY_TMPDIR=/var/tmp\nflyto myserver\nflyas myuser\n```` \n\n* `FLY_TARZ` variable can be set to customize tar compression used for teleportation (default `-z` uses gzip, recommended `-J` to use xz is your servers have xz installed).\n\n`thefly` is using a ssh embedded RemoteCommand containing compressed tar/base64 of your `.fly.d` if size under 128K (maximum command size), if size exceeds 128K, thefly will need to connect twice (once to transfer fly package, then spawn shell)\n\n* Putting your env in `~/.fly.d/.flyrc` will be automatically sourced (must be compatible with different shells, using fish won't source `.flyrc`)\n\n* Putting additional shell specific env in `~/.fly.d/.\u003cshellname\u003erc` (.bashrc/.kshrc/.zshrc), will be automatically sourced for shell.\n\nanything in `~/.fly.d` will be available through ssh/sudo (flyto/flyas) in `$FLY_HOME/.fly.d`\n\nFor example, just put your `.vimrc` in `~/.fly.d` and add in `~/.fly.d/.flyrc`:\n```\nexport VIMINIT=\"source $FLY_HOME/.fly.d/.vimrc\"\n```\nsame for `.inputrc`, put it in `~/.fly.d` and add in `~/.fly.d/.flyrc`:\n```\nexport INPUTRC=\"$FLY_HOME/.fly.d/.inputrc\"\n```\nYou can create a `.fly.d/bin` directory and put scripts you want to teleport and add in your `.fly.d/.flyrc`:\n```\nexport PATH=\"$PATH:$FLY_HOME/.fly.d/bin\"\n```\n\n## Standalone fly package \n\nSave your whole shell environment to use everywhere with standalone fly package.\n\nAll your ~/.fly.d environment saved in autoextractable file. The fly package enables your env when sourced.\n\nBuild your fly package (you can copy and use it directly to get your env or make it available on web server to remote download)  \n```\nflypack \u003efly.pak\n```\nThen use your fly.pak anywhere :\n\n`. ./fly.pak` : to activate your environment (in `/tmp/.fly.$USER`)\n\n`. ./fly.pak install` : to extract in ~/.fly.d and activate\n\nTo activate from url:\n```\n. \u003c(curl -sL https://raw.githubusercontent.com/joknarf/flypack/main/fly.pak)\n```\nto connect to a server with your env in `/tmp/.fly.$USER`, your can use:\n```\n$ ssh -t \u003chost\u003e '. \u003c(curl -sL https://raw.githubusercontent.com/joknarf/flypack/main/fly.pak) [bash|ksh|zsh]'\n```\nConnect to all servers with your fly pak from url with ssh config:\n```\nRequestTTY yes\nRemoteCommand . \u003c(curl -sL https://raw.githubusercontent.com/joknarf/flypack/main/fly.pak)\n```\n\n## Activate from git repo or url\n\nput your .fly.d directory into a git repo and activate all your env/plugins in your current user\n```\n. \u003c(curl https://raw.githubusercontent.com/joknarf/thefly/main/thefly) install joknarf/myfly\n```\n\ncreate a tgz file with your .fly.d exposed on web server and activate env/plugins in your current user\n```\n. \u003c(curl https://raw.githubusercontent.com/joknarf/thefly/main/thefly) install https://myserver/myfly.tgz\n```\n\n## joknarf cool plugins\n\n```\n$ fly add joknarf/nerdp        # bash/ksh/zsh nerd prompt\n$ fly add joknarf/seedee       # bash/ksh/zsh cd history\n$ fly add joknarf/redo         # bash/zsh     command history\n$ fly add joknarf/complete-ng  # bash/zsh     completion next-gen\nor just add the optimized compilation of these shell plugins using just:\n$ fly add joknarf/shell-ng\n\n$ fly add joknarf/pgtree       # bash/ksh/zsh process hierarchy\n$ fly add joknarf/lsicon       # ls enhancer (colors/icons)\n$ fly add joknarf/dfbar        # df enhancer (colors/usage bar)\n```\n\n|link                                                 |description                                                             |\n|-----------------------------------------------------|------------------------------------------------------------------------|\n|[nerdp](https://github.com/joknarf/nerdp)            |nerd dynamic customizable nice prompt                                   |\n|[seedee](https://github.com/joknarf/seedee)          |access/search dir history with ctrl or shift down arrow, and many more  |\n|[redo](https://github.com/joknarf/redo)              |access/search shell history command menu with shift-tab, and many more  |\n|[complete-ng](https://github.com/joknarf/complete-ng)|autocompletion with interactive menu                                    |\n|__[shell-ng](https://github.com/joknarf/shell-ng)__  |__optimized joknarf compilation of the above plugins__                  |\n|[pgtree](https://github.com/joknarf/pgtree)          |process search / tree / kill command line                               | \n|[lsicon](https://github.com/joknarf/lsicon)          |ls command enhancer (colors/icons)                                      | \n|[dfbar](https://github.com/joknarf/dfbar)            |df command enhancer (colors/usage bar)                                  | \n\n## Don't teleport a human with your fly !\n\nRemember that `~/.fly.d` directory will be duplicated in `/tmp` when teleporting, don't put huge data in your `~/.fly.d` directory, the consequences could be dramatic ! (ask Jeff G. ;-)\n\nBy choice, the `/tmp/.fly.$USER` is not removed at end of shell session, as multiple session may use the same fly env (other choice would be to duplicate same .fly.d for each session but can be overkill)\n\nThe files will remain and will be only be cleared by OS tmpfiles mechanism, the ideal size is to stay below 128K.\n\n(typically thefly will use a ssh config RemoteCommand for the duplication+connect, but if size is over 128K, will use 2 ssh connection, ssh duplicate + ssh interactive connect) \n\nBzzz Bzzz\n","funding_links":[],"categories":["Shell"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjoknarf%2Fthefly","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjoknarf%2Fthefly","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjoknarf%2Fthefly/lists"}