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

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

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


当前回答

注意:如果这个想法不明显,除了别名之外,使用别名是一个坏主意,第一个是“别名中的函数”,第二个是“难以读取的重定向/源”。此外,还有一些缺陷(我认为这是显而易见的,但以防万一你会感到困惑:我并不是说它们真的可以在任何地方使用!)


我以前回答过这个问题,过去总是这样:

alias foo='__foo() { unset -f $0; echo "arg1 for foo=$1"; }; __foo()'

这是很好的,除非你避免一起使用函数。在这种情况下,您可以利用bash强大的重定向文本的能力:

alias bar='cat <<< '\''echo arg1 for bar=$1'\'' | source /dev/stdin'

它们的长度大致相同,只需几个字符即可。

真正的关键是时间差,顶部是“函数方法”,底部是“重定向源”方法。为了证明这一理论,时机不言自明:

arg1 for foo=FOOVALUE
 real 0m0.011s user 0m0.004s sys 0m0.008s  # <--time spent in foo
 real 0m0.000s user 0m0.000s sys 0m0.000s  # <--time spent in bar
arg1 for bar=BARVALUE
ubuntu@localhost /usr/bin# time foo FOOVALUE; time bar BARVALUE
arg1 for foo=FOOVALUE
 real 0m0.010s user 0m0.004s sys 0m0.004s
 real 0m0.000s user 0m0.000s sys 0m0.000s
arg1 for bar=BARVALUE
ubuntu@localhost /usr/bin# time foo FOOVALUE; time bar BARVALUE
arg1 for foo=FOOVALUE
 real 0m0.011s user 0m0.000s sys 0m0.012s
 real 0m0.000s user 0m0.000s sys 0m0.000s
arg1 for bar=BARVALUE
ubuntu@localhost /usr/bin# time foo FOOVALUE; time bar BARVALUE
arg1 for foo=FOOVALUE
 real 0m0.012s user 0m0.004s sys 0m0.004s
 real 0m0.000s user 0m0.000s sys 0m0.000s
arg1 for bar=BARVALUE
ubuntu@localhost /usr/bin# time foo FOOVALUE; time bar BARVALUE
arg1 for foo=FOOVALUE
 real 0m0.010s user 0m0.008s sys 0m0.004s
 real 0m0.000s user 0m0.000s sys 0m0.000s
arg1 for bar=BARVALUE

这是随机间隔进行的约200个结果的底部。函数创建/销毁似乎比重定向花费更多的时间。希望这将有助于未来的访问者解决这个问题(我不想对自己保密)。

其他回答

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

Bash别名不直接接受参数。您必须创建一个函数。

alias不接受参数,但可以像别名一样调用函数。例如:

myfunction() {
    #do things with parameters like $1 such as
    mv "$1" "$1.bak"
    cp "$2" "$1"
}


myfunction old.conf new.conf #calls `myfunction`

顺便说一句,.bashrc和其他文件中定义的Bash函数可以作为shell中的命令使用。例如,您可以这样调用前面的函数

$ myfunction original.conf my.conf

以下是示例:

alias gcommit='function _f() { git add -A; git commit -m "$1"; } ; _f'

非常重要:

{后和{前有一个空格。有一个;依次在每个命令之后。如果您在最后一个命令后忘记了这一点,您将看到>提示符!参数用引号括起来,如“$1”

要具体回答有关创建别名以将文件移动到垃圾箱文件夹而不是删除文件的问题,请执行以下操作:

alias rm="mv "$1" -t ~/.Trash/"

当然,你必须先创建dir~/.Trash。

然后只需发出以下命令:

$rm <filename>
$rm <dirname>

具有子命令的解决方案:

d () {
    if [ $# -eq 0 ] ; then
        docker
        return 0
    fi
    CMD=$1
    shift

    case $CMD in
    p)
        docker ps --all $@
        ;;
    r)
        docker run --interactive --tty $@
        ;;
    rma)
        docker container prune
        docker image prune --filter "dangling=true"
        ;;
    *)
        docker $CMD $@
        ;;
    esac
    return $?
}

使用:

$ d r my_image ...

打电话:

docker run --interactive --tty my_image ...