1821 votes

Créer un alias Bash qui prend un paramètre ?

J'avais l'habitude d'utiliser CShell ( csh ), qui vous permet de créer un alias qui prend un paramètre. La notation était quelque chose comme

alias junk="mv \\!* ~/.Trash"

Dans Bash, cela ne semble pas fonctionner. Étant donné que Bash possède une multitude de fonctionnalités utiles, je suppose que celle-ci a été implémentée, mais je me demande comment.

3 votes

3 votes

Assurez-vous que vous utilisez des guillemets autour des args "$1"

1 votes

Cette question est hors sujet pour l'OS. Elle a été répondu sur UNIX.SE et la réponse est que vous n'avez même pas besoin de vous en soucier : "Par exemple, si vous deviez aliaser ls a ls -la puis en tapant ls foo bar serait vraiment exécuter ls -la foo bar sur la ligne de commande".

2voto

Ahmad Awais Points 9142

Pour prendre des paramètres, vous devez utiliser des fonctions !

Cependant, les $@ sont interprétés lors de la création de l'alias et non pendant l'exécution de l'alias et l'échappement des $ ne fonctionne pas non plus. Comment puis-je résoudre ce problème ?

Vous devez utiliser une fonction shell au lieu d'un alias pour vous débarrasser de ce problème. Vous pouvez définir foo comme suit :

function foo() { /path/to/command "$@" ;}

OU

foo() { /path/to/command "$@" ;}

Enfin, appelez votre foo() en utilisant la syntaxe suivante :

foo arg1 arg2 argN

Assurez-vous d'ajouter votre foo() à ~/.bash_profile o ~/.zshrc fichier.

Dans votre cas, cela fonctionnera

function trash() { mv $@ ~/.Trash; }

1voto

biocyberman Points 311

Les fonctions et les alias peuvent tous deux utiliser des paramètres, comme d'autres l'ont montré ici. En outre, je voudrais souligner quelques autres aspects :

1. La fonction s'exécute dans sa propre portée, l'alias partage la portée.

Il peut être utile de connaître cette différence dans les cas où vous devez cacher ou exposer quelque chose. Cela suggère également qu'une fonction est le meilleur choix pour l'encapsulation.

function tfunc(){
    GlobalFromFunc="Global From Func" # Function set global variable by default
    local FromFunc="onetwothree from func" # Set a local variable

}

alias talias='local LocalFromAlias="Local from Alias";  GlobalFromAlias="Global From Alias" # Cant hide a variable with local here '
# Test variables set by tfunc
tfunc # call tfunc
echo $GlobalFromFunc # This is visible
echo $LocalFromFunc # This is not visible
# Test variables set by talias
# call talias
talias
echo $GlobalFromAlias # This is invisible
echo $LocalFromAlias # This variable is unset and unusable 

Sortie :

bash-3.2$     # Test variables set by tfunc
bash-3.2$     tfunc # call tfunc
bash-3.2$     echo $GlobalFromFunc # This is visible
Global From Func
bash-3.2$     echo $LocalFromFunc # This is not visible

bash-3.2$     # Test variables set by talias
bash-3.2$     # call talias
bash-3.2$     talias
bash: local: can only be used in a function
bash-3.2$     echo $GlobalFromAlias # This is invisible
Global From Alias
bash-3.2$ echo $LocalFromAlias # This variable is unset and unusable

2. le wrapper script est un meilleur choix

Il m'est arrivé à plusieurs reprises qu'un alias ou une fonction ne soit pas trouvée lorsque se connecter via ssh ou impliquant un changement de nom d'utilisateur ou un environnement multi-utilisateurs. Il y a des trucs et astuces avec les fichiers point de source, ou cet intéressant avec les alias : alias sd='sudo ' laisse cet alias ultérieur alias install='sd apt-get install' fonctionnent comme prévu (remarquez l'espace supplémentaire dans sd='sudo ' ). Cependant, un wrapper script fonctionne mieux qu'une fonction ou un alias dans des cas comme celui-ci. Le principal avantage avec un wrapper script est qu'il est visible/exécutable pour sous le chemin prévu (i.e. /usr/loca/bin/) alors qu'une fonction/alias doit être sourcée avant d'être utilisable. Par exemple, vous mettez une fonction dans un ~/.bash_profile ou ~/.bashrc pour bash mais passer ensuite à un autre interpréteur de commandes (c'est-à-dire zsh ) alors la fonction n'est plus visible. Ainsi, lorsque vous avez un doute, un wrapper script est toujours la solution la plus fiable et la plus portable.

-1voto

d9k Points 47
alias junk="delay-arguments mv _ ~/.Trash"

delay-arguments script :

#!/bin/bash

# Example:
# > delay-arguments echo 1 _ 3 4 2
# 1 2 3 4
# > delay-arguments echo "| o n e" _ "| t h r e e" "| f o u r" "| t w o"
# | o n e | t w o | t h r e e | f o u r

RAW_ARGS=("$@")

ARGS=()

ARG_DELAY_MARKER="_"
SKIPPED_ARGS=0
SKIPPED_ARG_NUM=0
RAW_ARGS_COUNT="$#"

for ARG in "$@"; do
  #echo $ARG
  if [[ "$ARG" == "$ARG_DELAY_MARKER" ]]; then
    SKIPPED_ARGS=$((SKIPPED_ARGS+1))
  fi
done

for ((I=0; I<$RAW_ARGS_COUNT-$SKIPPED_ARGS; I++)); do
  ARG="${RAW_ARGS[$I]}"
  if [[ "$ARG" == "$ARG_DELAY_MARKER" ]]; then
    MOVE_SOURCE_ARG_NUM=$(($RAW_ARGS_COUNT-$SKIPPED_ARGS+$SKIPPED_ARG_NUM))
    MOVING_ARG="${RAW_ARGS[$MOVE_SOURCE_ARG_NUM]}"
    if [[ "$MOVING_ARG" == "$ARG_DELAY_MARKER" ]]; then
      echo "Error: Not enough arguments!"
      exit 1;
    fi
    #echo "Moving arg: $MOVING_ARG"
    ARGS+=("$MOVING_ARG")
    SKIPPED_ARG_NUM=$(($SKIPPED_ARG_NUM+1))
  else
    ARGS+=("$ARG")
  fi
done

#for ARG in "${ARGS[@]}"; do
  #echo "ARGN: $ARG"
#done

#echo "RAW_ARGS_COUNT: $RAW_ARGS_COUNT"
#echo "SKIPPED_ARGS: $SKIPPED_ARGS"

#echo "${ARGS[@]}"
QUOTED_ARGS=$(printf ' %q' "${ARGS[@]}")
eval "${QUOTED_ARGS[@]}"

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X