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

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

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


当前回答

函数和别名都可以使用其他函数和别名所示的参数。此外,我想指出几个其他方面:

1.函数在自己的作用域中运行,别名共享作用域

在需要隐藏或暴露某些内容的情况下,了解这种差异可能很有用。它还表明,函数是封装的更好选择。

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 

输出:

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.包装脚本是更好的选择

在我身上发生过几次,当通过ssh登录或涉及切换用户名或多用户环境时,找不到别名或函数。源点文件有一些提示和技巧,或者这个有趣的别名:aliassd='sudo'让这个后续的别名aliasinstall='sd-apt-get-install'按预期工作(注意sd='udo'中的额外空间)。然而,在这种情况下,包装脚本比函数或别名更有效。包装器脚本的主要优点是它在预期路径(即/usr/loca/bin/)下是可见的/可执行的,其中作为函数/别名需要在其可用之前获取。例如,您将一个函数放在~/.bash_profile或~/.bahrc中用于bash,但稍后切换到另一个shell(即zsh),则该函数不再可见。因此,当您有疑问时,包装脚本始终是最可靠和可移植的解决方案。

其他回答

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

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

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

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

我会发布我的(希望是好的)解决方案(对于未来的读者,最重要的是编辑)。所以,请编辑并改进/删除本文中的任何内容。

在终端中:

$ alias <name_of_your_alias>_$argname="<command> $argname"

并使用它(注意“_”后面的空格:

$<name_of_your_alias>_ $argname

例如,cat文件hello.txt的别名:

(别名为CAT_FILE_)$f(是$argname,在本例中是一个文件)

$ alias CAT_FILE_$f="cat $f"

$ echo " " >> hello.txt
$ echo "hello there!" >> hello.txt
$ echo " " >> hello.txt
$ cat hello.txt

    hello there!

测试(注意“_”后面的空格):

CAT_FILE_ hello.txt

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

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

具有子命令的解决方案:

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 ...