我曾经使用CShell(csh),它允许您创建一个接受参数的别名。符号有点像

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

在巴什,这似乎行不通。鉴于Bash有许多有用的特性,我会假设这一特性已经实现,但我想知道如何实现。


当前回答

TL;DR:改为这样做

与别名相比,使用函数在命令中间放置参数要容易得多,也更具可读性。

$ wrap_args() { echo "before $@ after"; }
$ wrap_args 1 2 3
before 1 2 3 after

如果你继续读下去,你会学到一些你不需要知道的关于shell参数处理的东西。知识是危险的。只要得到你想要的结果,在黑暗面永远控制你的命运之前。

澄清

bash别名确实接受参数,但仅在末尾:

$ alias speak=echo
$ speak hello world
hello world

通过别名将参数放在命令中间确实是可能的,但这会变得很难看。

孩子们,不要在家里尝试这个!

如果你喜欢规避限制,做别人说不可能做的事,下面是食谱。如果你的头发被磨烂了,你的脸上布满了科学家式的烟灰,不要怪我。

解决方法是将别名只在末尾接受的参数传递给包装器,包装器将在中间插入这些参数,然后执行命令。

解决方案1

如果您确实反对使用函数本身,可以使用:

$ alias wrap_args='f(){ echo before "$@" after;  unset -f f; }; f'
$ wrap_args x y z
before x y z after

如果只需要第一个参数,可以将$@替换为$1。

解释1

这将创建一个临时函数f,传递给参数(注意f是在最后调用的)。unset-f在执行别名时删除函数定义,这样以后它就不会再出现了。

解决方案2

您也可以使用子外壳:

$ alias wrap_args='sh -c '\''echo before "$@" after'\'' _'

解释2

别名生成如下命令:

sh -c 'echo before "$@" after' _

评论:

占位符_是必需的,但它可以是任何内容。它被设置为sh的$0,并且是必需的,以便用户给定的第一个参数不会被消耗。演示:sh-c'echo消费:“$0”打印:“$@”'酒后胡言乱语消费:酒精印刷:醉酒胡言乱语单引号内的单引号是必填的。下面是一个不使用双引号的示例:$sh-c“echo消耗:$0打印:$@”酒后胡言乱语消耗:-bash打印:在这里,交互式shell的$0和$@的值在传递给sh之前被替换为双引号echo“消耗:$0打印:$@”消耗:-bash打印:单引号确保这些变量不会被交互式shell解释,并按字面传递给sh-c。你可以使用双引号和\$@,但最好的做法是引用你的论点(因为它们可能包含空格),而“\$@\”看起来更难看,但可能会帮助你赢得一场混淆比赛,在这场比赛中,凌乱的头发是参赛的先决条件。

其他回答

为了尊重那些说你不能在别名中间插入参数的人,我刚刚测试了它,发现它确实有效。

alias mycommand = "python3 "$1" script.py --folderoutput RESULTS/"

然后,当我运行mycommandfoobar时,它的工作方式就好像我用长手键入了命令一样。

Bash别名绝对不接受参数。我只是添加了一个别名来创建一个新的react应用程序,它接受应用程序名称作为参数。以下是我的流程:

在nano中打开bash_profile进行编辑

nano /.bash_profile

添加别名,每行一个:

alias gita='git add .'
alias gitc='git commit -m "$@"'
alias gitpom='git push origin master'
alias creact='npx create-react-app "$@"'

注意:“$@”接受传入的参数,如“创建我的新应用程序”

保存并退出nano编辑器

ctrl+o to to to write(按回车键);ctrl+x退出

告诉终端使用.bash_profile中的新别名

source /.bash_profile

就是这样!现在可以使用新别名

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

延迟参数脚本:

#!/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[@]}"

正如其他人已经指出的,使用函数应被视为最佳实践。

然而,这里有另一种方法,利用xargs:

alias junk="xargs -I "{}" -- mv "{}" "~/.Trash" <<< "

注意,这会对流的重定向产生副作用。

下面是我的~/.bashrc中的三个函数示例,它们本质上是接受参数的别名:

#Utility required by all below functions.
#https://stackoverflow.com/questions/369758/how-to-trim-whitespace-from-bash-variable#comment21953456_3232433
alias trim="sed -e 's/^[[:space:]]*//g' -e 's/[[:space:]]*\$//g'"

.

:<<COMMENT
    Alias function for recursive deletion, with are-you-sure prompt.

    Example:
        srf /home/myusername/django_files/rest_tutorial/rest_venv/

    Parameter is required, and must be at least one non-whitespace character.

    Short description: Stored in SRF_DESC

    With the following setting, this is *not* added to the history:
        export HISTIGNORE="*rm -r*:srf *"
    - https://superuser.com/questions/232885/can-you-share-wisdom-on-using-histignore-in-bash

    See:
    - y/n prompt: https://stackoverflow.com/a/3232082/2736496
    - Alias w/param: https://stackoverflow.com/a/7131683/2736496
COMMENT
#SRF_DESC: For "aliaf" command (with an 'f'). Must end with a newline.
SRF_DESC="srf [path]: Recursive deletion, with y/n prompt\n"
srf()  {
    #Exit if no parameter is provided (if it's the empty string)
        param=$(echo "$1" | trim)
        echo "$param"
        if [ -z "$param" ]  #http://tldp.org/LDP/abs/html/comparison-ops.html
        then
          echo "Required parameter missing. Cancelled"; return
        fi

    #Actual line-breaks required in order to expand the variable.
    #- https://stackoverflow.com/a/4296147/2736496
    read -r -p "About to
    sudo rm -rf \"$param\"
Are you sure? [y/N] " response
    response=${response,,}    # tolower
    if [[ $response =~ ^(yes|y)$ ]]
    then
        sudo rm -rf "$param"
    else
        echo "Cancelled."
    fi
}

.

:<<COMMENT
    Delete item from history based on its line number. No prompt.

    Short description: Stored in HX_DESC

    Examples
        hx 112
        hx 3

    See:
    - https://unix.stackexchange.com/questions/57924/how-to-delete-commands-in-history-matching-a-given-string
COMMENT
#HX_DESC: For "aliaf" command (with an 'f'). Must end with a newline.
HX_DESC="hx [linenum]: Delete history item at line number\n"
hx()  {
    history -d "$1"
}

.

:<<COMMENT
    Deletes all lines from the history that match a search string, with a
    prompt. The history file is then reloaded into memory.

    Short description: Stored in HXF_DESC

    Examples
        hxf "rm -rf"
        hxf ^source

    Parameter is required, and must be at least one non-whitespace character.

    With the following setting, this is *not* added to the history:
        export HISTIGNORE="*hxf *"
    - https://superuser.com/questions/232885/can-you-share-wisdom-on-using-histignore-in-bash

    See:
    - https://unix.stackexchange.com/questions/57924/how-to-delete-commands-in-history-matching-a-given-string
COMMENT
#HXF_DESC: For "aliaf" command (with an 'f'). Must end with a newline.
HXF_DESC="hxf [searchterm]: Delete all history items matching search term, with y/n prompt\n"
hxf()  {
    #Exit if no parameter is provided (if it's the empty string)
        param=$(echo "$1" | trim)
        echo "$param"
        if [ -z "$param" ]  #http://tldp.org/LDP/abs/html/comparison-ops.html
        then
          echo "Required parameter missing. Cancelled"; return
        fi

    read -r -p "About to delete all items from history that match \"$param\". Are you sure? [y/N] " response
    response=${response,,}    # tolower
    if [[ $response =~ ^(yes|y)$ ]]
    then
        #Delete all matched items from the file, and duplicate it to a temp
        #location.
        grep -v "$param" "$HISTFILE" > /tmp/history

        #Clear all items in the current sessions history (in memory). This
        #empties out $HISTFILE.
        history -c

        #Overwrite the actual history file with the temp one.
        mv /tmp/history "$HISTFILE"

        #Now reload it.
        history -r "$HISTFILE"     #Alternative: exec bash
    else
        echo "Cancelled."
    fi
}

参考文献:

从字符串中删除空白:如何从Bash变量中删除空白?实际换行符:https://stackoverflow.com/a/4296147/2736496别名w/param:https://stackoverflow.com/a/7131683/2736496(这个问题的另一个答案)组氨酸:https://superuser.com/questions/232885/can-you-share-wisdom-on-using-histignore-in-bashY/N提示:https://stackoverflow.com/a/3232082/2736496从历史记录中删除所有匹配项:https://unix.stackexchange.com/questions/57924/how-to-delete-commands-in-history-matching-a-given-string字符串是否为空:http://tldp.org/LDP/abs/html/comparison-ops.html