做一個帶有參數的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. 我喜歡這種基於$@的解決方案,因爲它可用於任何數量的參數。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章