做一个带有参数的Bash别名?

本文翻译自:Make a Bash alias that takes a parameter?

I used to use CShell ( ), which lets you make an alias that takes a parameter. 我曾经使用CShell( ),它使您可以创建一个带参数的别名。 The notation was something like 记号有点像

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

In Bash, this does not seem to work. 在Bash中,这似乎不起作用。 Given that Bash has a multitude of useful features, I would assume that this one has been implemented but I am wondering how. 鉴于Bash具有许多有用的功能,我想假设该功能已实现,但我想知道如何实现。


#1楼

参考:https://stackoom.com/question/TvGw/做一个带有参数的Bash别名


#2楼

Refining the answer above, you can get 1-line syntax like you can for aliases, which is more convenient for ad-hoc definitions in a shell or .bashrc files: 细化上面的答案,您可以像别名一样获得一线语法,这对于shell或.bashrc文件中的即席定义更方便:

bash$ myfunction() { mv "$1" "$1.bak" && cp -i "$2" "$1"; }

bash$ myfunction original.conf my.conf

Don't forget the semi-colon before the closing right-bracket. 不要忘记右括号前的分号。 Similarly, for the actual question: 同样,对于实际问题:

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

bash$ junk() { mv "$@" ~/.Trash/; }

Or: 要么:

bash$ junk() { for item in "$@" ; do echo "Trashing: $item" ; mv "$item" ~/.Trash/; done; }

#3楼

Here's are three examples of functions I have in my ~/.bashrc , that are essentially aliases that accept a parameter: 这是我在~/.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
}

References: 参考文献:


#4楼

NB: In case the idea isn't obvious, it is a bad idea to use aliases for anything but aliases, the first one being the 'function in an alias' and the second one being the 'hard to read redirect/source'. 注意:如果这个主意不明显,则对别名以外的任何东西都使用别名是一个坏主意,第一个是“别名中的函数”,第二个是“难以读取的重定向/源代码”。 Also, there are flaws (which i thought would be obvious, but just in case you are confused: I do not mean them to actually be used... anywhere!) 此外,还有缺陷(我认为这很明显,但以防万一您感到困惑:我并不是说它们可以在任何地方被实际使用!)

................................................................................................................................................ ................................................... ................................................... .....................................................

I've answered this before, and it has always been like this in the past: 我之前已经回答过,过去一直都是这样:

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

which is fine and good, unless you are avoiding the use of functions all together. 除非您避免同时使用函数,否则这是很好的做法。 in which case you can take advantage of bash's vast ability to redirect text: 在这种情况下,您可以利用bash强大的重定向文本功能:

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

They are both about the same length give or take a few characters. 它们的长度大致相同,但要输入或输入几个字符。

The real kicker is the time difference, the top being the 'function method' and the bottom being the 'redirect-source' method. 真正的关键是时差,最上面是“函数方法”,最下面是“重定向源”方法。 To prove this theory, the timing speaks for itself: 为了证明这一理论,时机不言而喻:

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

This is the bottom part of about 200 results, done at random intervals. 这是大约200个结果的底部,以随机间隔进行。 It seems that function creation/destruction takes more time than redirection. 函数创建/销毁似乎比重定向花费更多时间。 Hopefully this will help future visitors to this question (didn't want to keep it to myself). 希望这可以帮助将来的访客解决这个问题(不想自己回答这个问题)。


#5楼

An alternative solution is to use marker , a tool I've created recently that allows you to "bookmark" command templates and easily place cursor at command place-holders: 一种替代解决方案是使用marker ,这是我最近创建的工具,可让您“添加书签”命令模板并将光标轻松放置在命令占位符上:

命令行标记

I found that most of time, I'm using shell functions so I don't have to write frequently used commands again and again in the command-line. 我发现大多数时候,我都在使用shell函数,因此不必在命令行中一次又一次地编写常用命令。 The issue of using functions for this use case, is adding new terms to my command vocabulary and having to remember what functions parameters refer to in the real-command. 在此用例中使用函数的问题是在我的命令词汇表中添加了新术语,并且必须记住实际命令中指的是哪些函数参数。 Marker goal is to eliminate that mental burden. 标志的目标是消除这种精神负担。


#6楼

If you're looking for a generic way to apply all params to a function, not just one or two or some other hardcoded amount, you can do that this way: 如果您正在寻找一种将所有参数应用于一个函数的通用方法,而不仅仅是一个或两个或一些其他硬编码量,则可以通过以下方式实现:

#!/usr/bin/env bash

# you would want to `source` this file, maybe in your .bash_profile?
function runjar_fn(){
    java -jar myjar.jar "$@";
}

alias runjar=runjar_fn;

So in the example above, i pass all parameters from when i run runjar to the alias. 因此,在上面的示例中,我将运行runjar时的所有参数传递给别名。

For example, if i did runjar hi there it would end up actually running java -jar myjar.jar hi there . 例如,如果我在runjar hi there运行runjar hi there ,它将最终实际运行java -jar myjar.jar hi there If i did runjar one two three it would run java -jar myjar.jar one two three . 如果我确实runjar one two three那么它将运行java -jar myjar.jar one two three

I like this $@ - based solution because it works with any number of params. 我喜欢这种基于$@的解决方案,因为它可用于任何数量的参数。

发布了0 篇原创文章 · 获赞 73 · 访问量 55万+

猜你喜欢

转载自blog.csdn.net/w36680130/article/details/105269593