GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Einführung in das Linux-Goto-Shell-Dienstprogramm

Das Goto-Shell-Dienstprogramm ermöglicht Benutzern das Navigieren zu Alias-Verzeichnissen und unterstützt auch die automatische Vervollständigung.

Wie es funktioniert

Bevor Sie goto verwenden können, müssen Sie Ihre Verzeichnis-Aliasse registrieren. Zum Beispiel:

goto -r dev /home/iridakos/development

Wechseln Sie dann in dieses Verzeichnis, z. B.:

goto dev

Autocompletion in goto

gehe zu kommt mit einem netten Skript zur automatischen Vervollständigung – jedes Mal, wenn Sie die Tab-Taste nach dem gehe zu drücken Befehl, Bash oder Zsh werden Sie mit Vorschlägen für die verfügbaren Aliase auffordern:

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

Installieren von goto

Es gibt mehrere Möglichkeiten, goto.

zu installieren

Über Skript

Klonen Sie das Repository und führen Sie das Installationsskript als Superuser oder Root aus:

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

Manuell

Kopieren Sie die Datei goto.sh irgendwo in Ihrem Dateisystem und fügen Sie eine Zeile in Ihre .zshrc ein oder .bashrc um es zu beschaffen.

Wenn Sie die Datei beispielsweise in Ihrem Home-Ordner abgelegt haben, müssen Sie lediglich die folgende Zeile zu Ihrer .zshrc hinzufügen oder .bashrc Datei:

source ~/goto.sh

MacOS-Homebrew

Eine Formel namens goto ist für die Bash-Shell in MacOS verfügbar:

brew install goto

Farbige Ausgabe hinzufügen

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

Hinweise:

  • Sie müssen Ihre Shell nach der Installation neu starten.
  • Sie müssen die Bash-Vervollständigungsfunktion für Bash in MacOS aktiviert haben (siehe diese Ausgabe).
    • Sie können es mit brew install bash-completion installieren wenn Sie es nicht aktiviert haben.

Möglichkeiten zur Verwendung von goto

In ein Alias-Verzeichnis wechseln

Um zu einem Alias-Verzeichnis zu wechseln, geben Sie Folgendes ein:

goto <alias>

Zum Beispiel:

goto dev

Alias ​​registrieren

Geben Sie zum Registrieren eines Verzeichnisaliasnamens Folgendes ein:

goto -r <alias> <directory>

oder

goto --register <alias> <directory>

Zum Beispiel:

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

oder

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

Hinweise:

  • gehe zu erweitert die Verzeichnisse, sodass Sie Ihr aktuelles Verzeichnis einfach mit dem folgenden Befehl aliasieren können und es wird automatisch dem gesamten Pfad zugeordnet:
    goto -r last_release .
  • Durch Drücken der Tabulatortaste nach dem Aliasnamen werden die Standardverzeichnisvorschläge der Shell angezeigt.

Alias ​​abmelden

Um einen Alias ​​abzumelden, verwenden Sie:

goto -u <alias>

oder

goto --unregister <alias>

Zum Beispiel:

goto -u last_release

oder

goto --unregister last_release

Hinweis: Durch Drücken der Tab-Taste nach dem Befehl (-u oder --abmelden ), fordert Sie das Vervollständigungsskript mit der Liste der registrierten Aliase auf.

Aliase auflisten

Um eine Liste Ihrer derzeit registrierten Aliase zu erhalten, verwenden Sie:

goto -l

oder

goto --list

Einen Alias ​​erweitern

Um einen Alias ​​auf seinen Wert zu erweitern, verwenden Sie:

goto -x <alias>

oder

goto --expand <alias>

Zum Beispiel:

goto -x last_release

oder

goto --expand last_release

Aliase bereinigen

Um die Aliase aus Verzeichnissen zu bereinigen, auf die in Ihrem Dateisystem nicht mehr zugegriffen werden kann, verwenden Sie:

goto -c

oder

goto --cleanup

Holen Sie sich Hilfe

Um die Hilfeinformationen des Tools anzuzeigen, verwenden Sie:

goto -h

oder

goto --help

Prüfen Sie die Version

Um die Version des Tools anzuzeigen, verwenden Sie:

goto -v

oder

goto --version

Push vor Verzeichniswechsel

Geben Sie Folgendes ein, um das aktuelle Verzeichnis auf den Verzeichnisstapel zu verschieben, bevor Sie das Verzeichnis wechseln:

goto -p <alias>

oder

goto --push <alias>

Kehre zu einem gepushten Verzeichnis zurück

Geben Sie Folgendes ein, um zu einem gepushten Verzeichnis zurückzukehren:

goto -o

oder

goto --pop

Hinweis: Dieser Befehl entspricht popd aber innerhalb des goto Befehl.

Fehlerbehebung

Wenn Sie den Fehler Befehl nicht gefunden:compdef sehen in Zsh bedeutet dies, dass Sie bashcompinit laden müssen . Hängen Sie dies dazu an Ihre .zshrc an Datei:

autoload bashcompinit
bashcompinit

Beteiligen Sie sich

Das goto-Tool ist Open Source unter den MIT-Lizenzbedingungen, und Beiträge sind willkommen. Um mehr zu erfahren, besuchen Sie den Abschnitt „Contributing“ im GitHub-Repository von goto.

Das goto-Skript

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


Dies wurde ursprünglich als README im GitHub-Repository von goto veröffentlicht und wird mit Genehmigung wiederverwendet.


Linux
  1. Eine Einführung in die Verwendung von tcpdump auf der Linux-Befehlszeile

  2. Befehlszeilenaliase in der Linux-Shell

  3. Einführung in den Alternativen-Befehl in Linux

  4. So ändern Sie die Standard-Shell in Linux

  5. So ändern Sie die Standard-Shell in Linux

Eine Einführung in den Terminalemulator DomTerm für Linux

Einführung in das Linux-Dateisystem

Was ist die Shell unter Linux?

So installieren Sie Fish, die freundliche interaktive Shell, unter Linux

So ändern Sie die Standard-Shell im Linux-System

Linux-Shell-Sortierdatei nach der zweiten Spalte?