cbwin icon indicating copy to clipboard operation
cbwin copied to clipboard

Default command handler

Open poma opened this issue 7 years ago • 10 comments

Here is a script for people that want to use WSL like Cygwin. If command is not found on Linux it will attempt to run it on windows automatically:

# Whether to attempt to run command from %USERPROFILE% dir.
# This is useful when current path can't be translated to a windows path.
# Also potentially dangerous for example if you run windows delete commands
# in /tmp it may actually delete your windows home dir
ATTEMPT_TO_RUN_IN_HOME_DIR=false

# Choose one from 'wcmd', 'wrun', 'wstart'
COMMAND="wrun"

try_cbwin() {
    if [[ $# -gt 0 ]]; then
        if $COMMAND where "$1" > /dev/null 2>&1; then
            $COMMAND "$@"
            return 0
        fi
        if [ "$ATTEMPT_TO_RUN_IN_HOME_DIR" = true ] && $COMMAND : where "$1" > /dev/null 2>&1; then
            $COMMAND : "$@"
            return 0
        fi
    fi

    return 1
}

save_old_command_handler() {
    if declare -f command_not_found_handler > /dev/null; then
        eval "$(echo "orig_command_not_found_handler(){"; declare -f $1 | tail -n +2)"
        OLD_COMMAND_HANDLER=true
    else
        OLD_COMMAND_HANDLER=false
    fi
}

command_not_found_chain_handler() {
    if try_cbwin "$@"; then
        return 0
    elif [ $OLD_COMMAND_HANDLER = true ]; then
        orig_command_not_found_handler "$@"
        return $?
    else
        return 1
    fi
}

case "${SHELL}" in
    */zsh)
        save_old_command_handler "command_not_found_handler"
        command_not_found_handler() {
            command_not_found_chain_handler "$@"
            return $?
        }
        ;;
    */bash)
        save_old_command_handler "command_not_found_handle"
        command_not_found_handle() {
            command_not_found_chain_handler "$@"
            return $?
        }
        ;;
esac

Just save this script to a file and add source this_script.sh to .bashrc or .zshrc depending on your shell. This is pretty basic implementation, feel free to improve it

poma avatar Aug 10 '16 22:08 poma

@poma hi, i'm having some little troubles with this, first, i couldn't ever change my shell to zsh with chsh command, so i start my outbash.exe with ~ -c "zsh --login", so i'm entering to the bash case, because my $SHELL variable is "/bin/bash", then i changed it to command_not_found_handler() to get it properly working, but the thing is that the if statement of try_cbwin gets executed and throws an error because is trying to find a "which" file, if i change it to $COMMAND "$1" then i get the command executed twice, my question is, is this only happening to me because i didn't change the shell properly? and if you could walk me through that if statement on what is doing, i don't really know that much about shell scripting, i know this > /dev/null 2>&1 is for redirect the error output(right?xd), but the first part and what is the which for, no clue, i would really like to have this working and also add support, eventually, for the case of been on the home_directory and automatically append the : for using windows_home_path in those cases, thanks in advance, regards!

zerocool4u2 avatar Aug 11 '16 14:08 zerocool4u2

Try sudo chsh -s /bin/zsh yourUser

The idea of this script is to run which command in windows shell to determine if a file (first argument) exists. We are not interested in its output (hence > /dev/null 2>&1), we just need the return code. If it succeeds then run the whole command in windows. Obviously it will work only for executables and not built-in cmd commands.

I've just realized that my script uses which command provided by Cygwin and that's why it doesn't work on your machine. The windows equivalent for which is where. I've fixed my script to reflect that.

poma avatar Aug 11 '16 14:08 poma

Also updated script to allow commands from home dir (false by default) but be careful with it

poma avatar Aug 11 '16 15:08 poma

thanks man! works perfect!! i couldn't be happier right now, i really appreciated, chsh in the other hand, still not working, i just change "command_not_found_handle" to "handler" for now, if it becomes a problem in the future, so it be lol, thanks again man and take care, regards! PD: time to delete all those aliases =)

zerocool4u2 avatar Aug 11 '16 15:08 zerocool4u2

Cool script! Any idea if Ctrl-Z can be made to work properly with it? Oddly suspension is propagated to the win32 side but I don't get back the shell prompt (tried with bash)

xilun avatar Aug 11 '16 20:08 xilun

Update about Ctrl-Z: hm and it's not just because of the use of a function and not even because of the use of command_not_found_handle. Weird. I will take another look later.

xilun avatar Aug 11 '16 20:08 xilun

Found a bug: this script will override default command-not-found script that suggests to install packages when command is not found (enabled in bash by default and in zsh via command-not-found plugin). Updated my script to copy and invoke old function if it is defined. Also I've missed quotes around @$ in first version. Result is a bit verbose and probably still has some bugs as I have no experience with bash

poma avatar Aug 11 '16 22:08 poma

@xilun Ctrl-Z works for me. I can successfully freeze notepad, get shell prompt, and then unfreeze it.

poma avatar Aug 11 '16 23:08 poma

More testing: with this command not found handler, Ctrl-Z works under zsh, but not bash. This might be a bash bug or a WSL bug, I'm looking into it.

xilun avatar Aug 12 '16 22:08 xilun

This seems to be mainly a bash bug, however the behavior of bash is actually worse on a real Linux system in this case (Ctrl-C after a Ctrl-Z does not work), so there might also be a WSL bug (which in this case slightly improves the usability) to find in there :p

xilun avatar Aug 13 '16 00:08 xilun