GNU/Linux >> Tutoriales Linux >  >> Linux

Introducción a la utilidad goto shell de Linux

La utilidad goto shell permite a los usuarios navegar a directorios con alias y también admite el autocompletado.

Cómo funciona

Antes de poder usar goto, debe registrar sus alias de directorio. Por ejemplo:

goto -r dev /home/iridakos/development

luego cambie a ese directorio, por ejemplo:

goto dev

Autocompletar en ir a

ir a viene con una buena secuencia de comandos de autocompletado, cada vez que presiona la tecla Tabulador después de ir a comando, Bash o Zsh le sugerirán los alias disponibles:

$ goto <tab>
bc /etc/bash_completion.d                    
dev /home/iridakos/development
rubies /home/iridakos/.rvm/rubies

Instalando goto

Hay varias formas de instalar goto.

A través de script

Clone el repositorio y ejecute el script de instalación como superusuario o root:

git clone https://github.com/iridakos/goto.git
cd goto
sudo ./install

Manualmente

Copie el archivo goto.sh en algún lugar de su sistema de archivos y agregue una línea en su .zshrc o .bashrc para obtenerlo.

Por ejemplo, si colocó el archivo en su carpeta de inicio, todo lo que tiene que hacer es agregar la siguiente línea a su .zshrc o .bashrc archivo:

source ~/goto.sh

Mac OS Homebrew

Una fórmula llamada goto está disponible para el shell Bash en MacOS:

brew install goto

Añadir salida de color

echo -e "\$include /etc/inputrc\nset colored-completion-prefix on" >> ~/.inputrc

Notas:

  • Debe reiniciar su shell después de la instalación.
  • Debe tener habilitada la función de finalización de Bash para Bash en MacOS (consulte este problema).
    • Puedes instalarlo con brew install bash-completion si no lo tiene habilitado.

Formas de usar goto

Cambiar a un directorio con alias

Para cambiar a un directorio con alias, escriba:

goto <alias>

Por ejemplo:

goto dev

Registrar un alias

Para registrar un alias de directorio, escriba:

goto -r <alias> <directory>

o

goto --register <alias> <directory>

Por ejemplo:

goto -r blog /mnt/external/projects/html/blog

o

goto --register blog /mnt/external/projects/html/blog

Notas:

  • ir a expande los directorios, por lo que puede asignar fácilmente un alias a su directorio actual con el siguiente comando y automáticamente se le asignará un alias a toda la ruta:
    goto -r last_release .
  • Al presionar la tecla Tabulador después del nombre de alias, se proporcionan las sugerencias de directorio predeterminadas del shell.

Anular el registro de un alias

Para cancelar el registro de un alias, utilice:

goto -u <alias>

o

goto --unregister <alias>

Por ejemplo:

goto -u last_release

o

goto --unregister last_release

Nota: Presionando la tecla Tab después del comando (-u o --darse de baja ), el script de finalización le mostrará la lista de alias registrados.

Lista de alias

Para obtener una lista de sus alias registrados actualmente, use:

goto -l

o

goto --list

Expandir un alias

Para expandir un alias a su valor, use:

goto -x <alias>

o

goto --expand <alias>

Por ejemplo:

goto -x last_release

o

goto --expand last_release

Limpiar alias

Para limpiar los alias de los directorios a los que ya no se puede acceder en su sistema de archivos, use:

goto -c

o

goto --cleanup

Obtener ayuda

Para ver la información de ayuda de la herramienta, utilice:

goto -h

o

goto --help

Verificar la versión

Para ver la versión de la herramienta, use:

goto -v

o

goto --version

Pulsar antes de cambiar directorios

Para insertar el directorio actual en la pila de directorios antes de cambiar de directorio, escriba:

goto -p <alias>

o

goto --push <alias>

Revertir a un directorio push

Para volver a un directorio enviado, escriba:

goto -o

o

goto --pop

Nota: Este comando es equivalente a popd pero dentro del goto comando.

Solución de problemas

Si ve el error comando no encontrado:compdef en Zsh, significa que necesita cargar bashcompinit . Para hacerlo, agregue esto a su .zshrc archivo:

autoload bashcompinit
bashcompinit

Involúcrate

La herramienta goto es de código abierto bajo los términos de la licencia MIT y se agradecen las contribuciones. Para obtener más información, visite la sección de contribuciones en el repositorio de GitHub de goto.

La secuencia de comandos Ir a

goto()
{
  local target
  _goto_resolve_db

  if [ -z "$1" ]; then
    # display usage and exit when no args
    _goto_usage
    return
  fi

  subcommand="$1"
  shift
  case "$subcommand" in
    -c|--cleanup)
      _goto_cleanup "$@"
      ;;
    -r|--register) # Register an alias
      _goto_register_alias "$@"
      ;;
    -u|--unregister) # Unregister an alias
      _goto_unregister_alias "$@"
      ;;
    -p|--push) # Push the current directory onto the pushd stack, then goto
      _goto_directory_push "$@"
      ;;
    -o|--pop) # Pop the top directory off of the pushd stack, then change that directory
      _goto_directory_pop
      ;;
    -l|--list)
      _goto_list_aliases
      ;;
    -x|--expand) # Expand an alias
      _goto_expand_alias "$@"
      ;;
    -h|--help)
      _goto_usage
      ;;
    -v|--version)
      _goto_version
      ;;
    *)
      _goto_directory "$subcommand"
      ;;
  esac
  return $?
}

_goto_resolve_db()
{
  GOTO_DB="${GOTO_DB:-$HOME/.goto}"
  touch -a "$GOTO_DB"
}

_goto_usage()
{
  cat <<\USAGE
usage: goto [<option>] <alias> [<directory>]

default usage:
  goto <alias> - changes to the directory registered for the given alias

OPTIONS:
  -r, --register: registers an alias
    goto -r|--register <alias> <directory>
  -u, --unregister: unregisters an alias
    goto -u|--unregister <alias>
  -p, --push: pushes the current directory onto the stack, then performs goto
    goto -p|--push <alias>
  -o, --pop: pops the top directory from the stack, then changes to that directory
    goto -o|--pop
  -l, --list: lists aliases
    goto -l|--list
  -x, --expand: expands an alias
    goto -x|--expand <alias>
  -c, --cleanup: cleans up non existent directory aliases
    goto -c|--cleanup
  -h, --help: prints this help
    goto -h|--help
  -v, --version: displays the version of the goto script
    goto -v|--version
USAGE
}

# Displays version
_goto_version()
{
  echo "goto version 1.2.4.1"
}

# Expands directory.
# Helpful for ~, ., .. paths
_goto_expand_directory()
{
  builtin cd "$1" 2>/dev/null && pwd
}

# Lists registered aliases.
_goto_list_aliases()
{
  local IFS=$' '
  if [ -f "$GOTO_DB" ]; then
    while read -r name directory; do
      printf '\e[1;36m%20s  \e[0m%s\n' "$name" "$directory"
    done < "$GOTO_DB"
  else
    echo "You haven't configured any directory aliases yet."
  fi
}

# Expands a registered alias.
_goto_expand_alias()
{
  if [ "$#" -ne "1" ]; then
    _goto_error "usage: goto -x|--expand <alias>"
    return
  fi

  local resolved

  resolved=$(_goto_find_alias_directory "$1")
  if [ -z "$resolved" ]; then
    _goto_error "alias '$1' does not exist"
    return
  fi

  echo "$resolved"
}

# Lists duplicate directory aliases
_goto_find_duplicate()
{
  local duplicates=

  duplicates=$(sed -n 's:[^ ]* '"$1"'$:&:p' "$GOTO_DB" 2>/dev/null)
  echo "$duplicates"
}

# Registers and alias.
_goto_register_alias()
{
  if [ "$#" -ne "2" ]; then
    _goto_error "usage: goto -r|--register <alias> <directory>"
    return 1
  fi

  if ! [[ $1 =~ ^[[:alnum:]]+[a-zA-Z0-9_-]*$ ]]; then
    _goto_error "invalid alias - can start with letters or digits followed by letters, digits, hyphens or underscores"
    return 1
  fi

  local resolved
  resolved=$(_goto_find_alias_directory "$1")

  if [ -n "$resolved" ]; then
    _goto_error "alias '$1' exists"
    return 1
  fi

  local directory
  directory=$(_goto_expand_directory "$2")
  if [ -z "$directory" ]; then
    _goto_error "failed to register '$1' to '$2' - can't cd to directory"
    return 1
  fi

  local duplicate
  duplicate=$(_goto_find_duplicate "$directory")
  if [ -n "$duplicate" ]; then
    _goto_warning "duplicate alias(es) found: \\n$duplicate"
  fi

  # Append entry to file.
  echo "$1 $directory" >> "$GOTO_DB"
  echo "Alias '$1' registered successfully."
}

# Unregisters the given alias.
_goto_unregister_alias()
{
  if [ "$#" -ne "1" ]; then
    _goto_error "usage: goto -u|--unregister <alias>"
    return 1
  fi

  local resolved
  resolved=$(_goto_find_alias_directory "$1")
  if [ -z "$resolved" ]; then
    _goto_error "alias '$1' does not exist"
    return 1
  fi

  # shellcheck disable=SC2034
  local readonly GOTO_DB_TMP="$HOME/.goto_"
  # Delete entry from file.
  sed "/^$1 /d" "$GOTO_DB" > "$GOTO_DB_TMP" && mv "$GOTO_DB_TMP" "$GOTO_DB"
  echo "Alias '$1' unregistered successfully."
}

# Pushes the current directory onto the stack, then goto
_goto_directory_push()
{
  if [ "$#" -ne "1" ]; then
    _goto_error "usage: goto -p|--push <alias>"
    return
  fi

  { pushd . || return; } 1>/dev/null 2>&1

  _goto_directory "$@"
}

# Pops the top directory from the stack, then goto
_goto_directory_pop()
{
  { popd || return; } 1>/dev/null 2>&1
}

# Unregisters aliases whose directories no longer exist.
_goto_cleanup()
{
  if ! [ -f "$GOTO_DB" ]; then
    return
  fi

  while IFS= read -r i && [ -n "$i" ]; do
    echo "Cleaning up: $i"
    _goto_unregister_alias "$i"
  done <<< "$(awk '{al=$1; $1=""; dir=substr($0,2);
                    system("[ ! -d \"" dir "\" ] && echo " al)}' "$GOTO_DB")"
}

# Changes to the given alias' directory
_goto_directory()
{
  local target

  target=$(_goto_resolve_alias "$1") || return 1

  builtin cd "$target" 2> /dev/null || \
    { _goto_error "Failed to goto '$target'" && return 1; }
}

# Fetches the alias directory.
_goto_find_alias_directory()
{
  local resolved

  resolved=$(sed -n "s/^$1 \\(.*\\)/\\1/p" "$GOTO_DB" 2>/dev/null)
  echo "$resolved"
}

# Displays the given error.
# Used for common error output.
_goto_error()
{
  (>&2 echo -e "goto error: $1")
}

# Displays the given warning.
# Used for common warning output.
_goto_warning()
{
  (>&2 echo -e "goto warning: $1")
}

# Displays entries with aliases starting as the given one.
_goto_print_similar()
{
  local similar

  similar=$(sed -n "/^$1[^ ]* .*/p" "$GOTO_DB" 2>/dev/null)
  if [ -n "$similar" ]; then
    (>&2 echo "Did you mean:")
    (>&2 column -t <<< "$similar")
  fi
}

# Fetches alias directory, errors if it doesn't exist.
_goto_resolve_alias()
{
  local resolved

  resolved=$(_goto_find_alias_directory "$1")

  if [ -z "$resolved" ]; then
    _goto_error "unregistered alias $1"
    _goto_print_similar "$1"
    return 1
  else
    echo "${resolved}"
  fi
}

# Completes the goto function with the available commands
_complete_goto_commands()
{
  local IFS=$' \t\n'

  # shellcheck disable=SC2207
  COMPREPLY=($(compgen -W "-r --register -u --unregister -p --push -o --pop -l --list -x --expand -c --cleanup -v --version" -- "$1"))
}

# Completes the goto function with the available aliases
_complete_goto_aliases()
{
  local IFS=$'\n' matches
  _goto_resolve_db

  # shellcheck disable=SC2207
  matches=($(sed -n "/^$1/p" "$GOTO_DB" 2>/dev/null))

  if [ "${#matches[@]}" -eq "1" ]; then
    # remove the filenames attribute from the completion method
    compopt +o filenames 2>/dev/null

    # if you find only one alias don't append the directory
    COMPREPLY=("${matches[0]// *}")
  else
    for i in "${!matches[@]}"; do
      # remove the filenames attribute from the completion method
      compopt +o filenames 2>/dev/null

      if ! [[ $(uname -s) =~ Darwin* ]]; then
        matches[$i]=$(printf '%*s' "-$COLUMNS" "${matches[$i]}")

        COMPREPLY+=("$(compgen -W "${matches[$i]}")")
      else
        COMPREPLY+=("${matches[$i]// */}")
      fi
    done
  fi
}

# Bash programmable completion for the goto function
_complete_goto_bash()
{
  local cur="${COMP_WORDS[$COMP_CWORD]}" prev

  if [ "$COMP_CWORD" -eq "1" ]; then
    # if we are on the first argument
    if [[ $cur == -* ]]; then
      # and starts like a command, prompt commands
      _complete_goto_commands "$cur"
    else
      # and doesn't start as a command, prompt aliases
      _complete_goto_aliases "$cur"
    fi
  elif [ "$COMP_CWORD" -eq "2" ]; then
    # if we are on the second argument
    prev="${COMP_WORDS[1]}"

    if [[ $prev = "-u" ]] || [[ $prev = "--unregister" ]]; then
      # prompt with aliases if user tries to unregister one
      _complete_goto_aliases "$cur"
    elif [[ $prev = "-x" ]] || [[ $prev = "--expand" ]]; then
      # prompt with aliases if user tries to expand one
      _complete_goto_aliases "$cur"
    elif [[ $prev = "-p" ]] || [[ $prev = "--push" ]]; then
      # prompt with aliases only if user tries to push
      _complete_goto_aliases "$cur"
    fi
  elif [ "$COMP_CWORD" -eq "3" ]; then
    # if we are on the third argument
    prev="${COMP_WORDS[1]}"

    if [[ $prev = "-r" ]] || [[ $prev = "--register" ]]; then
      # prompt with directories only if user tries to register an alias
      local IFS=$' \t\n'

      # shellcheck disable=SC2207
      COMPREPLY=($(compgen -d -- "$cur"))
    fi
  fi
}

# Zsh programmable completion for the goto function
_complete_goto_zsh()
{
  local all_aliases=()
  while IFS= read -r line; do
    all_aliases+=("$line")
  done <<< "$(sed -e 's/ /:/g' ~/.goto 2>/dev/null)"

  local state
  local -a options=(
    '(1)'{-r,--register}'[registers an alias]:register:->register'
    '(- 1 2)'{-u,--unregister}'[unregisters an alias]:unregister:->unregister'
    '(: -)'{-l,--list}'[lists aliases]'
    '(*)'{-c,--cleanup}'[cleans up non existent directory aliases]'
    '(1 2)'{-x,--expand}'[expands an alias]:expand:->aliases'
    '(1 2)'{-p,--push}'[pushes the current directory onto the stack, then performs goto]:push:->aliases'
    '(*)'{-o,--pop}'[pops the top directory from stack, then changes to that directory]'
    '(: -)'{-h,--help}'[prints this help]'
    '(* -)'{-v,--version}'[displays the version of the goto script]'
  )

  _arguments -C \
    "${options[@]}" \
    '1:alias:->aliases' \
    '2:dir:_files' \
  && ret=0

  case ${state} in
    (aliases)
      _describe -t aliases 'goto aliases:' all_aliases && ret=0
    ;;
    (unregister)
      _describe -t aliases 'unregister alias:' all_aliases && ret=0
    ;;
  esac
  return $ret
}

goto_aliases=($(alias | sed -n "s/.*\s\(.*\)='goto'/\1/p"))
goto_aliases+=("goto")

for i in "${goto_aliases[@]}"
        do
                # Register the goto completions.
        if [ -n "${BASH_VERSION}" ]; then
          if ! [[ $(uname -s) =~ Darwin* ]]; then
            complete -o filenames -F _complete_goto_bash $i
          else
            complete -F _complete_goto_bash $i
          fi
        elif [ -n "${ZSH_VERSION}" ]; then
          compdef _complete_goto_zsh $i
        else
          echo "Unsupported shell."
          exit 1
        fi
done


Esto se publicó originalmente como README en el repositorio de GitHub de goto y se reutiliza con permiso.


Linux
  1. Haz matemáticas en el shell de Linux con GNU bc

  2. Introducción a los comandos chgrp y newgrp de Linux

  3. Introducción al comando chmod de Linux

  4. Introducción al comando chown de Linux

  5. Alias ​​de línea de comandos en el shell de Linux

Una introducción al emulador de terminal DomTerm para Linux

Introducción al sistema de archivos de Linux

Cómo crear un alias y usar el comando Alias ​​en Linux

¿Qué es el Shell en Linux?

Cómo instalar Fish, The Friendly Interactive Shell, en Linux

Cómo cambiar el shell predeterminado en el sistema Linux