From 4599d08a2996006a3268500afbfca5a0a9740618 Mon Sep 17 00:00:00 2001 From: Jintin Date: Sun, 2 Aug 2026 10:05:02 +0800 Subject: [PATCH] fix: correct alias matching, portable prompts, and exit codes - Match names pair-wise in _excute/_remove via new _find helper so a command line that equals another alias name can no longer execute the wrong entry or corrupt the store on removal - Replace bash-only read -rep/-pr prompts (broken under zsh, and al rm with no args errored in both shells) with portable printf + read -r - Propagate real exit codes: al returns the command's status and unknown names return 1 - Reject duplicate and empty names in al add - Declare function variables local and use IFS= on read loops so sourcing no longer clobbers shell variables Co-Authored-By: Claude Fable 5 --- aliasme.sh | 132 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 87 insertions(+), 45 deletions(-) diff --git a/aliasme.sh b/aliasme.sh index 1e01fa5..cc728fa 100644 --- a/aliasme.sh +++ b/aliasme.sh @@ -5,85 +5,123 @@ ALIASME_DIR="${ALIASME_DIR:-$HOME/.aliasme}" ALIASME_CMD="$ALIASME_DIR/cmd" _list() { + local name value if [ -s "$ALIASME_CMD" ];then - while read -r name + while IFS= read -r name do - if ! read -r value; then break; fi + if ! IFS= read -r value; then break; fi echo "$name : $value" done < "$ALIASME_CMD" fi } +_find() { + local name + if [ -s "$ALIASME_CMD" ];then + while IFS= read -r name + do + if [ "$1" = "$name" ]; then + return 0 + fi + if ! IFS= read -r _; then break; fi + done < "$ALIASME_CMD" + fi + return 1 +} + _add() { # Ensure directory exists mkdir -p "$ALIASME_DIR" + local name cmd name=$1 if [ -z "$1" ]; then - read -rep "Input name to add:" name + printf "Input name to add: " + IFS= read -r name fi cmd="$2" if [ -z "$2" ]; then - read -rep "Input cmd to add:" cmd + printf "Input cmd to add: " + IFS= read -r cmd + fi + + if [ -z "$name" ] || [ -z "$cmd" ]; then + echo "name and command must not be empty" + return 1 + fi + + if _find "$name"; then + echo "$name already exists, remove it first: al rm $name" + return 1 fi echo "$name" >> "$ALIASME_CMD" echo "$cmd" >> "$ALIASME_CMD" - echo "add: $name -> $cmd" + echo "add: $name -> $cmd" _autocomplete } _remove() { + local name value line found name=$1 if [ -z "$1" ]; then - read -pr "Input name to remove:" name + printf "Input name to remove: " + IFS= read -r name fi - if [ -s "$ALIASME_CMD" ];then - touch "$ALIASME_DIR/cmdtemp" - while read -r line - do - if [ "$line" = "$name" ]; then - read -r _ #skip one more line - echo "remove $name" - else - echo "$line" >> "$ALIASME_DIR/cmdtemp" - fi - done < "$ALIASME_CMD" - mv "$ALIASME_DIR/cmdtemp" "$ALIASME_CMD" - fi + found=1 + if [ -s "$ALIASME_CMD" ];then + : > "$ALIASME_DIR/cmdtemp" + while IFS= read -r line + do + if ! IFS= read -r value; then break; fi + if [ "$line" = "$name" ]; then + echo "remove $name" + found=0 + else + echo "$line" >> "$ALIASME_DIR/cmdtemp" + echo "$value" >> "$ALIASME_DIR/cmdtemp" + fi + done < "$ALIASME_CMD" + mv "$ALIASME_DIR/cmdtemp" "$ALIASME_CMD" + fi + if [ "$found" -ne 0 ]; then + echo "not found: $name" + fi _autocomplete + return "$found" } _excute() { - if [ -s "$ALIASME_CMD" ];then - while read -u9 -r line; do - if [ "$1" = "$line" ]; then - read -u9 -r line - eval "$line" - return 0 - fi - done 9< "$ALIASME_CMD" - fi + local name value + if [ -s "$ALIASME_CMD" ];then + while IFS= read -u9 -r name; do + if ! IFS= read -u9 -r value; then break; fi + if [ "$1" = "$name" ]; then + eval "$value" + return $? + fi + done 9< "$ALIASME_CMD" + fi return 1 } _bashauto() { - local cur opts + local cur opts line COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" opts="" - if [ -s "$ALIASME_CMD" ];then - while read -r line - do - opts+=" $line" - read -r _ - done < "$ALIASME_CMD" - fi + if [ -s "$ALIASME_CMD" ];then + while IFS= read -r line + do + opts+=" $line" + if ! IFS= read -r _; then break; fi + done < "$ALIASME_CMD" + fi # shellcheck disable=SC2207 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -91,16 +129,17 @@ _bashauto() _autocomplete() { + local opts line if [ -n "$ZSH_VERSION" ]; then # zsh opts="" - if [ -s "$ALIASME_CMD" ];then - while read -r line - do - opts+="$line " - read -r _ - done < "$ALIASME_CMD" - fi + if [ -s "$ALIASME_CMD" ];then + while IFS= read -r line + do + opts+="$line " + if ! IFS= read -r _; then break; fi + done < "$ALIASME_CMD" + fi # shellcheck disable=SC2154 compctl -k "($opts)" al else @@ -131,8 +170,11 @@ al(){ echo "aliasme 3.1.0" echo "visit https://github.com/Jintin/aliasme for more information" else - if ! _excute "$1" ; then - echo "not found" + if _find "$1"; then + _excute "$1" + else + echo "not found: $1" + return 1 fi fi fi