diff --git a/README.md b/README.md
index 8ff9275..f2dcef8 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,6 @@
-
NO PUBLICAR
-
# configuraciones Ubuntu
- ConfiguraciĆ³n Wifi en HP Pavilion. [WifiES.txt](doc/WifiES.txt)
- Script actualizaciones de paquetes apt y snap. [actualizar.sh](src/actualizar.sh)
- Script de pruebas de red. [pruebaRed.sh](src/pruebaRed.sh)
+- Script para seleccionar contextos con kubectl [kubeselect](src/kubeselect)
diff --git a/src/kubeselect b/src/kubeselect
new file mode 100755
index 0000000..5d8db37
--- /dev/null
+++ b/src/kubeselect
@@ -0,0 +1,348 @@
+#!/usr/bin/env bash
+
+# This small helper util helps select an available Kubernetes context using the arrow keys
+# using one simple command rather than two seperate kubectl commands to first show, then select contexts.
+# It uses the mapfile shim found here: https://github.com/dosentmatter/bash-mapfile-shim
+# which itself uses upvars by Freddy Vulto: http://fvue.nl/wiki/Bash:_Passing_variables_by_reference
+# These are only needed for bash versions < 4, otherwise the native functions are used.
+#
+# Finally, the small select_option function was found on this Stackoverflow thread:
+# https://stackoverflow.com/questions/11426529/reading-output-of-a-command-into-an-array-in-bash
+# I included all source code I used as is.
+
+# Bash: Passing variables by reference
+# Copyright (C) 2010 Freddy Vulto
+# Version: upvars-0.9.dev
+# See: http://fvue.nl/wiki/Bash:_Passing_variables_by_reference
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+
+# Assign variable one scope above the caller
+# Usage: local "$1" && upvar $1 "value(s)"
+# Param: $1 Variable name to assign value to
+# Param: $* Value(s) to assign. If multiple values, an array is
+# assigned, otherwise a single value is assigned.
+# NOTE: For assigning multiple variables, use 'upvars'. Do NOT
+# use multiple 'upvar' calls, since one 'upvar' call might
+# reassign a variable to be used by another 'upvar' call.
+# Example:
+#
+# f() { local b; g b; echo $b; }
+# g() { local "$1" && upvar $1 bar; }
+# f # Ok: b=bar
+#
+upvar() {
+ if unset -v "$1"; then # Unset & validate varname
+ if (( $# == 2 )); then
+ eval $1=\"\$2\" # Return single value
+ else
+ eval $1=\(\"\${@:2}\"\) # Return array
+ fi
+ fi
+}
+
+
+# Assign variables one scope above the caller
+# Usage: local varname [varname ...] &&
+# upvars [-v varname value] | [-aN varname [value ...]] ...
+# Available OPTIONS:
+# -aN Assign next N values to varname as array
+# -v Assign single value to varname
+# Return: 1 if error occurs
+# Example:
+#
+# f() { local a b; g a b; declare -p a b; }
+# g() {
+# local c=( foo bar )
+# local "$1" "$2" && upvars -v $1 A -a${#c[@]} $2 "${c[@]}"
+# }
+# f # Ok: a=A, b=(foo bar)
+#
+upvars() {
+ if ! (( $# )); then
+ echo "${FUNCNAME[0]}: usage: ${FUNCNAME[0]} [-v varname"\
+ "value] | [-aN varname [value ...]] ..." 1>&2
+ return 2
+ fi
+ while (( $# )); do
+ case $1 in
+ -a*)
+ # Error checking
+ [[ ${1#-a} ]] || { echo "bash: ${FUNCNAME[0]}: \`$1': missing"\
+ "number specifier" 1>&2; return 1; }
+ printf %d "${1#-a}" &> /dev/null || { echo "bash:"\
+ "${FUNCNAME[0]}: \`$1': invalid number specifier" 1>&2
+ return 1; }
+ # Assign array of -aN elements
+ [[ "$2" ]] && unset -v "$2" && eval $2=\(\"\${@:3:${1#-a}}\"\) &&
+ shift $((${1#-a} + 2)) || { echo "bash: ${FUNCNAME[0]}:"\
+ "\`$1${2+ }$2': missing argument(s)" 1>&2; return 1; }
+ ;;
+ -v)
+ # Assign single value
+ [[ "$2" ]] && unset -v "$2" && eval $2=\"\$3\" &&
+ shift 3 || { echo "bash: ${FUNCNAME[0]}: $1: missing"\
+ "argument(s)" 1>&2; return 1; }
+ ;;
+ --help) echo "\
+Usage: local varname [varname ...] &&
+ ${FUNCNAME[0]} [-v varname value] | [-aN varname [value ...]] ...
+Available OPTIONS:
+-aN VARNAME [value ...] assign next N values to varname as array
+-v VARNAME value assign single value to varname
+--help display this help and exit
+--version output version information and exit"
+ return 0 ;;
+ --version) echo "\
+${FUNCNAME[0]}-0.9.dev
+Copyright (C) 2010 Freddy Vulto
+License GPLv3+: GNU GPL version 3 or later
+This is free software: you are free to change and redistribute it.
+There is NO WARRANTY, to the extent permitted by law."
+ return 0 ;;
+ *)
+ echo "bash: ${FUNCNAME[0]}: $1: invalid option" 1>&2
+ return 1 ;;
+ esac
+ done
+}
+
+# use mapfile_function if mapfile not found
+mapfile() {
+ if type -f mapfile &>/dev/null; then
+ command mapfile "$@"
+ else
+ mapfile_function "$@"
+ fi
+}
+
+# Behaves like bash 4.x mapfile.
+mapfile_function() {
+ local DELIM=$'\n'
+ local REMOVE_TRAILING_DELIM='false'
+ local OUTPUT_ARRAY_NAME='MAPFILE'
+
+ local OPTIND OPTARG OPTERR
+ local option
+ OPTERR=0
+ while getopts ':d:n:O:s:tu:C:c:' option; do
+ case "$option" in
+ d)
+ DELIM=$OPTARG
+ ;;
+ t)
+ REMOVE_TRAILING_DELIM='true'
+ ;;
+ :)
+ echo "Option requires an argument: -$OPTARG" >&2
+ return 1
+ ;;
+ \?)
+ echo "Illegal option: -$OPTARG" >&2
+ return 2
+ ;;
+ ?)
+ echo "Option unimplemented: -$option" >&2
+ return 3
+ ;;
+ esac
+ done
+
+ shift "$((OPTIND - 1))"
+
+ if (($# >= 1)); then
+ OUTPUT_ARRAY_NAME=$1
+ fi
+
+ local output_array=()
+ local null_end='false'
+ local REPLY
+ if [[ -n "$DELIM" ]]; then # stops at first null when DELIM is not null
+ IFS= read -r -d '' && null_end='true'
+ fi
+ while IFS= read -r -d "$DELIM"; do
+ if [[ "$REMOVE_TRAILING_DELIM" = 'true' ]]; then
+ output_array+=("$REPLY")
+ else
+ output_array+=("$REPLY$DELIM")
+ fi
+ done < <(
+ if [[ -n "$DELIM" ]]; then
+ echo -n "$REPLY"
+ [[ "$null_end" = 'true' ]] && printf '%b' '\0'
+ else
+ cat
+ fi
+ )
+ if [[ -n "$REPLY" ]] || [[ "$null_end" = 'true' ]]; then
+ output_array+=("$REPLY")
+ fi
+
+ local "$OUTPUT_ARRAY_NAME" &&
+ upvars -a"${#output_array[@]}" "$OUTPUT_ARRAY_NAME" "${output_array[@]}"
+}
+
+# mapfile according to word splitting rules.
+# This isn't used by the shim.
+# Empty lines aren't included in array if
+# DELIM is whitespace (space, tab, newline) or null.
+mapfile_IFS() {
+ local DELIM=$'\n'
+ local REMOVE_TRAILING_DELIM='false'
+ local OUTPUT_ARRAY_NAME='MAPFILE'
+
+ local OPTIND OPTARG OPTERR
+ local option
+ OPTERR=0
+ while getopts ':d:n:O:s:tu:C:c:' option; do
+ case "$option" in
+ d)
+ DELIM=$OPTARG
+ ;;
+ t)
+ REMOVE_TRAILING_DELIM='true'
+ ;;
+ :)
+ echo "Option requires an argument: -$OPTARG" >&2
+ return 1
+ ;;
+ \?)
+ echo "Illegal option: -$OPTARG" >&2
+ return 2
+ ;;
+ ?)
+ echo "Option unimplemented: -$option" >&2
+ return 3
+ ;;
+ esac
+ done
+
+ shift "$((OPTIND - 1))"
+
+ if (($# >= 1)); then
+ OUTPUT_ARRAY_NAME=$1
+ fi
+
+ local output_array=()
+ local null_end='false'
+ local delim_end='false'
+ local REPLY
+ local array_front
+ local array_last
+ if [[ -n "$DELIM" ]]; then
+ IFS= read -r -d '' && null_end='true'
+ [[ "$REPLY" = *"$DELIM" ]] && delim_end='true'
+ IFS=$DELIM read -r -d '' -a 'output_array' < <(
+ echo -n "$REPLY"
+ [[ "$null_end" = 'true' ]] && printf '%b' '\0'
+ )
+
+ if [[ "$REMOVE_TRAILING_DELIM" = 'false' ]]; then
+ array_front=("${output_array[@]:0:${#output_array[@]} - 1}")
+ array_last=${output_array[${#output_array[@]} - 1]}
+
+ array_front=("${array_front[@]/%/$DELIM}")
+ if [[ "$delim_end" = 'true' ]]; then
+ array_last+=$DELIM
+ fi
+
+ output_array=("${array_front[@]}" "$array_last")
+ fi
+ else
+ while IFS=$DELIM read -r -d ''; do
+ # no need to append null trailing delim because vars can't hold null
+ [[ -n "$REPLY" ]] && output_array+=("$REPLY")
+ done
+ [[ -n "$REPLY" ]] && output_array+=("$REPLY")
+ fi
+
+ local "$OUTPUT_ARRAY_NAME" &&
+ upvars -a"${#output_array[@]}" "$OUTPUT_ARRAY_NAME" "${output_array[@]}"
+}
+
+
+# Renders a text based list of options that can be selected by the
+# user using up, down and enter keys and returns the chosen option.
+#
+# Arguments : list of options, maximum of 256
+# "opt1" "opt2" ...
+# Return value: selected index (0 for opt1, 1 for opt2 ...)
+function select_option {
+
+ # little helpers for terminal print control and key input
+ ESC=$( printf "\033")
+ cursor_blink_on() { printf "$ESC[?25h"; }
+ cursor_blink_off() { printf "$ESC[?25l"; }
+ cursor_to() { printf "$ESC[$1;${2:-1}H"; }
+ print_option() { printf " $1 "; }
+ print_selected() { printf " $ESC[7m $1 $ESC[27m"; }
+ get_cursor_row() { IFS=';' read -sdR -p $'\E[6n' ROW COL; echo ${ROW#*[}; }
+ key_input() { read -s -n3 key 2>/dev/null >&2
+ if [[ $key = $ESC[A ]]; then echo up; fi
+ if [[ $key = $ESC[B ]]; then echo down; fi
+ if [[ $key = "" ]]; then echo enter; fi; }
+
+ # initially print empty new lines (scroll down if at bottom of screen)
+ for opt; do printf "\n"; done
+
+ # determine current screen position for overwriting the options
+ local lastrow=`get_cursor_row`
+ local startrow=$(($lastrow - $#))
+
+ # ensure cursor and input echoing back on upon a ctrl+c during read -s
+ trap "cursor_blink_on; stty echo; printf '\n'; exit" 2
+ cursor_blink_off
+
+ local selected=0
+ while true; do
+ # print options by overwriting the last lines
+ local idx=0
+ for opt; do
+ cursor_to $(($startrow + $idx))
+ if [ $idx -eq $selected ]; then
+ print_selected "$opt"
+ else
+ print_option "$opt"
+ fi
+ ((idx++))
+ done
+
+ # user key control
+ case `key_input` in
+ enter) break;;
+ up) ((selected--));
+ if [ $selected -lt 0 ]; then selected=$(($# - 1)); fi;;
+ down) ((selected++));
+ if [ $selected -ge $# ]; then selected=0; fi;;
+ esac
+ done
+
+ # cursor position back to normal
+ cursor_to $lastrow
+ printf "\n"
+ cursor_blink_on
+
+ return $selected
+}
+
+mapfile -t available_contexts < <( kubectl config get-contexts -oname )
+
+echo "Select context using up/down keys and enter to confirm:"
+echo
+
+select_option "${available_contexts[@]}"
+choice=$?
+
+kubectl config use-context ${available_contexts[$choice]}