├── .github ├── FUNDING.yml └── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── feature_request.md │ └── other.md ├── .gitignore ├── LICENSE ├── README.md ├── build.sh ├── entrypoint.sh ├── requirements.txt ├── zsh.sh └── zshrc /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | #github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | #patreon: xonssh # Replace with a single Patreon username 5 | #open_collective: # Replace with a single Open Collective username 6 | #ko_fi: # Replace with a single Ko-fi username 7 | #tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | #community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | #liberapay: # Replace with a single Liberapay username 10 | #issuehunt: # Replace with a single IssueHunt username 11 | #otechie: # Replace with a single Otechie username 12 | custom: ['https://github.com/anki-code', 'https://www.buymeacoffee.com/xxh'] 13 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Local OS (where xxh is installed):** 11 | **Destination host OS:** 12 | **xxh version:** 13 | **xxh-plugins installed:** 14 | 15 | **Steps to Reproduce** 16 | 1. I run `xxh ... +v` 17 | 2. The output log: 18 | 3. What is the problem 19 | 20 | **For community:** 21 | ⬇️ **Please click the 👍 reaction instead of leaving a `+1` or 👍 comment** 22 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | 22 | **For community:** 23 | ⬇️ **Please click the 👍 reaction instead of leaving a `+1` or 👍 comment** 24 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/other.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Other 3 | about: Any other questions 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | 11 | 12 | **For community:** 13 | ⬇️ **Please click the 👍 reaction instead of leaving a `+1` or 👍 comment** 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | xxh 2 | squashfs-root 3 | appimage 4 | xxh-shell* 5 | xxh-plugin* 6 | *.pyc 7 | *.out 8 | *.xcf 9 | *.egg 10 | .eggs/ 11 | .pytest_cache/ 12 | build/ 13 | dist/ 14 | xxh_xxh.egg-info/ 15 | venv/ 16 | 17 | # temporary files from vim and emacs 18 | *~ 19 | *# 20 | .#* 21 | *.swp 22 | *.swo 23 | 24 | # Editor project files 25 | *.komodo* 26 | .cache 27 | .idea 28 | .vscode/ 29 | 30 | # Mac 31 | .DS_Store 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 2-Clause License 2 | 3 | Copyright (c) 2020, xxh 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 20 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | xxh entrypoint for romkatv/zsh-bin - statically-linked, hermetic, relocatable Zsh. 3 |

4 | 5 |

6 | If you like the idea of xxh click ⭐ on the repo and tweet. 7 |

8 | 9 | ## Install 10 | Install from xxh repo: 11 | ``` 12 | xxh +I xxh-shell-zsh 13 | ``` 14 | Install from any repo: 15 | ``` 16 | xxh +I xxh-shell-zsh+git+https://github.com/xxh/xxh-shell-zsh 17 | ``` 18 | Connect: 19 | ``` 20 | xxh myhost +s zsh 21 | ``` 22 | To avoid adding `+s` every time use xxh config in `~/.config/xxh/config.xxhc` (`$XDG_CONFIG_HOME`): 23 | ``` 24 | hosts: 25 | ".*": # Regex for all hosts 26 | +s: zsh 27 | ``` 28 | 29 | ## Plugins 30 | 31 | **zsh xxh plugin** is the set of zsh scripts which will be run when you'll use xxh. You can create xxh plugin with your lovely aliases, tools or color theme and xxh will bring them to your ssh sessions. 32 | 33 | 🔎 [Search xxh plugins on Github](https://github.com/search?q=xxh-plugin-zsh&type=Repositories) or [Bitbucket](https://bitbucket.org/repo/all?name=xxh-plugin-zsh) or 💡 [Create xxh plugin](https://github.com/xxh/xxh-plugin-zsh-example) 34 | 35 | Pinned xxh zsh plugins: [ohmyzsh](https://github.com/xxh/xxh-plugin-zsh-ohmyzsh), [powerlevel10k](https://github.com/xxh/xxh-plugin-zsh-powerlevel10k) 36 | 37 | ## Thanks 38 | * Roman Perepelitsa for [romkatv/zsh-bin](https://github.com/romkatv/zsh-bin) 39 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | CDIR="$(cd "$(dirname "$0")" && pwd)" 4 | 5 | while getopts A:K:q option 6 | do 7 | case "${option}" 8 | in 9 | q) QUIET=1;; 10 | A) ARCH=${OPTARG};; 11 | K) KERNEL=${OPTARG};; 12 | esac 13 | done 14 | 15 | build_dir=$CDIR/build 16 | 17 | rm -rf $build_dir 18 | mkdir -p $build_dir/zsh-bin 19 | 20 | for f in entrypoint.sh zsh.sh 21 | do 22 | cp $CDIR/$f $build_dir/ 23 | done 24 | cp $CDIR/zshrc $build_dir/.zshrc 25 | 26 | # tag=$(curl --silent https://api.github.com/repos/romkatv/zsh-bin/releases/latest | grep '"tag_name":' | cut -d'"' -f4) 27 | tag=v3.0.1 28 | arch=$(uname -m) 29 | if [[ $arch == x86_64* ]]; then 30 | distfile=zsh-5.8-linux-x86_64 31 | elif [[ $arch == arm* ]]; then 32 | distfile=zsh-5.8-linux-armv7l 33 | fi 34 | 35 | 36 | url="https://github.com/romkatv/zsh-bin/releases/download/$tag/$distfile.tar.gz" 37 | tarname=`basename $url` 38 | 39 | cd $build_dir/zsh-bin 40 | 41 | [ $QUIET ] && arg_q='-q' || arg_q='' 42 | [ $QUIET ] && arg_s='-s' || arg_s='' 43 | [ $QUIET ] && arg_progress='' || arg_progress='--progress bar' 44 | 45 | if [ -x "$(command -v wget)" ]; then 46 | wget $arg_q $arg_progress $url -O $tarname 47 | elif [ -x "$(command -v curl)" ]; then 48 | curl $arg_s -L $url -o $tarname 49 | else 50 | echo Install wget or curl 51 | fi 52 | 53 | tar -xzf $tarname 54 | if [[ $arch == x86_64* ]]; then 55 | mv zsh-5.8-linux-x86_64/* . 56 | elif [[ $arch == arm* ]]; then 57 | mv zsh-5.8-linux-armv7l/* . 58 | fi 59 | 60 | rm $tarname 61 | -------------------------------------------------------------------------------- /entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # 4 | # Support arguments (this recommend but not required): 5 | # -f Execute file on host, print the result and exit 6 | # -c [Not recommended to use] Execute command on host, print the result and exit 7 | # -C Execute command on host, print the result and exit 8 | # -v Verbose mode: 1 - verbose, 2 - super verbose 9 | # -e -e ... Environement variables (B64 is base64 encoded string) 10 | # -b -b ... Base64 encoded bash command 11 | # -H HOME path. Will be $HOME on the host. 12 | # -X XDG_* path (https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html) 13 | # 14 | 15 | while getopts f:c:C:v:e:b:H:X: option 16 | do 17 | case "${option}" 18 | in 19 | f) EXECUTE_FILE=${OPTARG};; 20 | c) EXECUTE_COMMAND=${OPTARG};; 21 | C) EXECUTE_COMMAND_B64=${OPTARG};; 22 | v) VERBOSE=${OPTARG};; 23 | e) ENV+=("$OPTARG");; 24 | b) EBASH+=("$OPTARG");; 25 | H) HOMEPATH=${OPTARG};; 26 | X) XDGPATH=${OPTARG};; 27 | esac 28 | done 29 | 30 | if [[ $VERBOSE != '' ]]; then 31 | export XXH_VERBOSE=$VERBOSE 32 | fi 33 | 34 | CURRENT_DIR="$(cd "$(dirname "$0")" && pwd)" 35 | export XXH_HOME=`readlink -f $CURRENT_DIR/../../../..` 36 | 37 | if [[ ! -d $XXH_HOME/.local/share/zsh ]]; then 38 | mkdir -p $XXH_HOME/.local/share/zsh 39 | fi 40 | 41 | if [[ $HOMEPATH != '' ]]; then 42 | homerealpath=`readlink -f $HOMEPATH` 43 | if [[ -d $homerealpath ]]; then 44 | export HOME=$homerealpath 45 | else 46 | echo "Home path not found: $homerealpath" 47 | echo "Set HOME to $XXH_HOME" 48 | export HOME=$XXH_HOME 49 | fi 50 | else 51 | export HOME=$XXH_HOME 52 | fi 53 | 54 | if [[ $XDGPATH != '' ]]; then 55 | xdgrealpath=`readlink -f $XDGPATH` 56 | if [[ ! -d $xdgrealpath ]]; then 57 | echo "XDG path not found: $xdgrealpath" 58 | echo "Set XDG path to $XXH_HOME" 59 | export XDGPATH=$XXH_HOME 60 | fi 61 | else 62 | export XDGPATH=$XXH_HOME 63 | fi 64 | 65 | 66 | export XXH_SHELL=zsh 67 | export XDG_CONFIG_HOME=$XDGPATH/.config 68 | export XDG_DATA_HOME=$XDGPATH/.local/share 69 | export XDG_CACHE_HOME=$XDGPATH/.cache 70 | export XAUTHORITY=/home/$USER/.Xauthority 71 | export TMPDIR=$XDG_CACHE_HOME/tmp 72 | export TEMP=$TMPDIR 73 | mkdir -p $TMPDIR 74 | 75 | if [[ $EXECUTE_COMMAND ]]; then 76 | if [[ $XXH_VERBOSE == '1' || $XXH_VERBOSE == '2' ]]; then 77 | echo Execute command: $EXECUTE_COMMAND 78 | fi 79 | 80 | EXECUTE_COMMAND=(-c "${EXECUTE_COMMAND}") 81 | fi 82 | 83 | if [[ $EXECUTE_COMMAND_B64 ]]; then 84 | EXECUTE_COMMAND=`echo $EXECUTE_COMMAND_B64 | base64 -d` 85 | if [[ $XXH_VERBOSE == '1' || $XXH_VERBOSE == '2' ]]; then 86 | echo Execute command base64: $EXECUTE_COMMAND_B64 87 | echo Execute command: $EXECUTE_COMMAND 88 | fi 89 | 90 | EXECUTE_COMMAND=(-c "${EXECUTE_COMMAND}") 91 | fi 92 | 93 | if [[ $EXECUTE_FILE ]]; then 94 | EXECUTE_COMMAND="" 95 | fi 96 | 97 | for env in "${ENV[@]}"; do 98 | name="$( cut -d '=' -f 1 <<< "$env" )"; 99 | val="$( cut -d '=' -f 2- <<< "$env" )"; 100 | val=`echo $val | base64 -d` 101 | # explicitly expand parameters 102 | val=$(eval "echo \"$val\"") 103 | 104 | if [[ $XXH_VERBOSE == '1' || $XXH_VERBOSE == '2' ]]; then 105 | echo Entrypoint env: raw="$env", name=$name, value=$val 106 | fi 107 | 108 | export $name="$val" 109 | done 110 | 111 | for eb in "${EBASH[@]}"; do 112 | bash_command=`echo $eb | base64 -d` 113 | 114 | if [[ $XXH_VERBOSE == '1' || $XXH_VERBOSE == '2' ]]; then 115 | echo Entrypoint bash execute: $bash_command 116 | fi 117 | eval $bash_command 118 | done 119 | 120 | cd $CURRENT_DIR 121 | 122 | # Check 123 | if [[ ! -f .entrypoint-check-done ]]; then 124 | check_result=`./zsh.sh --version 2>&1` 125 | if [[ $check_result != *"zsh "* ]]; then 126 | echo "Something went wrong while running zsh on host:" 127 | echo $check_result 128 | else 129 | echo $check_result > .entrypoint-check-done 130 | fi 131 | fi 132 | 133 | for pluginrc_file in $(find $CURRENT_DIR/../../../plugins/xxh-plugin-*/build -type f -name '*prerun.sh' -printf '%f\t%p\n' 2>/dev/null | sort -k1 | cut -f2); do 134 | if [[ -f $pluginrc_file ]]; then 135 | if [[ $XXH_VERBOSE == '1' || $XXH_VERBOSE == '2' ]]; then 136 | echo Load plugin $pluginrc_file 137 | fi 138 | #cd $(dirname $pluginrc_file) 139 | source $pluginrc_file 140 | fi 141 | done 142 | 143 | cd $HOME 144 | $CURRENT_DIR/zsh.sh $EXECUTE_FILE "${EXECUTE_COMMAND[@]}" 145 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | xxh-xxh 2 | -------------------------------------------------------------------------------- /zsh.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | CDIR="$(cd "$(dirname "$0")" && pwd)" 4 | 5 | zshbin='zsh-bin' 6 | 7 | zsh_dir='' 8 | if [ -f $CDIR/.zsh_dir ]; then 9 | zsh_dir=`cat $CDIR/.zsh_dir` 10 | fi 11 | 12 | if [ ! "$CDIR" = "$zsh_dir" ]; then 13 | if [ "$XXH_VERBOSE" = '2' ]; then 14 | $CDIR/$zshbin/share/zsh/5.8/scripts/relocate 15 | else 16 | $CDIR/$zshbin/share/zsh/5.8/scripts/relocate > /dev/null 2> /dev/null 17 | fi 18 | echo $CDIR > $CDIR/.zsh_dir 19 | fi 20 | 21 | mkdir -p $XDG_DATA_HOME/zsh 22 | 23 | export ZDOTDIR=$CDIR 24 | export PATH=$CDIR/$zshbin/bin:$PATH 25 | export SAVEHIST=10000 26 | export HISTFILE=$XDG_DATA_HOME/zsh/history 27 | 28 | $CDIR/$zshbin/bin/zsh "$@" 29 | -------------------------------------------------------------------------------- /zshrc: -------------------------------------------------------------------------------- 1 | CURRENT_DIR="$(cd "$(dirname "$0")" && pwd)" 2 | 3 | if [[ $XXH_VERBOSE == '2' ]]; then 4 | echo Run $CURRENT_DIR/../../.zshrc 5 | fi 6 | 7 | setopt +o nomatch 8 | for pluginrc_file in $(find $CURRENT_DIR/../../../../../plugins/*/build -type f -name '*pluginrc.zsh' -printf '%f\t%p\n' 2>/dev/null | sort -k1 | cut -f2); do 9 | if [[ -f $pluginrc_file ]]; then 10 | plugin_name=`basename $(dirname $(dirname $pluginrc_file))` 11 | 12 | # Search EXE environment variables for plugin and execute 13 | plugin_env_name=`echo $plugin_name | tr '[:lower:]' '[:upper:]' | sed 's/-/_/g'` 14 | prefix="$plugin_env_name"_EXE_ 15 | if [[ $XXH_VERBOSE == '2' ]]; then 16 | echo "Search $prefix*** environment for $plugin_name" 17 | fi 18 | for l in `env | grep $prefix`; do 19 | if [[ $XXH_VERBOSE == '2' ]]; then 20 | echo ENV $plugin_name: $l 21 | fi 22 | data="$( cut -d '=' -f 2- <<< "$l" )"; 23 | code=`echo $data | base64 -d` 24 | if [[ $XXH_VERBOSE == '2' ]]; then 25 | echo ENV $plugin_name RUN: $code 26 | fi 27 | eval $code 28 | done 29 | 30 | # Load plugin 31 | if [[ $XXH_VERBOSE == '1' || $XXH_VERBOSE == '2' ]]; then 32 | echo Load plugin $pluginrc_file 33 | fi 34 | source $pluginrc_file 35 | fi 36 | done 37 | setopt -o nomatch 38 | 39 | cd ~ 40 | --------------------------------------------------------------------------------