本文翻译自:Make a Bash alias that takes a parameter?
I used to use CShell ( csh ), which lets you make an alias that takes a parameter. 我曾经使用CShell( csh ),它使您可以创建一个带参数的别名。 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: 参考文献:
- Trimming whitespace from strings: How to trim whitespace from a Bash variable? 从字符串修剪空格: 如何从Bash变量修剪空格?
- Actual line breaks: https://stackoverflow.com/a/4296147/2736496 实际换行符: https : //stackoverflow.com/a/4296147/2736496
- Alias w/param: https://stackoverflow.com/a/7131683/2736496 (another answer in this question) 带参数的别名: https : //stackoverflow.com/a/7131683/2736496 (此问题的另一个答案)
- HISTIGNORE: https://superuser.com/questions/232885/can-you-share-wisdom-on-using-histignore-in-bash HISTIGNORE: https ://superuser.com/questions/232885/can-you-share-wisdom-on-using-histignore-in-bash
- Y/N prompt: https://stackoverflow.com/a/3232082/2736496 是/否提示: https : //stackoverflow.com/a/3232082/2736496
- Delete all matching items from history: https://unix.stackexchange.com/questions/57924/how-to-delete-commands-in-history-matching-a-given-string 从历史记录中删除所有匹配项: https : //unix.stackexchange.com/questions/57924/how-to-delete-commands-in-history-matching-a-given-string
- Is string null/empty: http://tldp.org/LDP/abs/html/comparison-ops.html 字符串是否为空/空: http : //tldp.org/LDP/abs/html/comparison-ops.html
#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. 我喜欢这种基于$@
的解决方案,因为它可用于任何数量的参数。