我曾经使用CShell(csh),它允许您创建一个接受参数的别名。符号有点像
alias junk="mv \\!* ~/.Trash"
在巴什,这似乎行不通。鉴于Bash有许多有用的特性,我会假设这一特性已经实现,但我想知道如何实现。
我曾经使用CShell(csh),它允许您创建一个接受参数的别名。符号有点像
alias junk="mv \\!* ~/.Trash"
在巴什,这似乎行不通。鉴于Bash有许多有用的特性,我会假设这一特性已经实现,但我想知道如何实现。
当前回答
完善上面的答案,您可以获得与别名类似的单行语法,这对于shell或.bashrc文件中的特殊定义更为方便:
bash$ myfunction() { mv "$1" "$1.bak" && cp -i "$2" "$1"; }
bash$ myfunction original.conf my.conf
不要忘记右右括号前的分号。同样,对于实际问题:
csh% alias junk="mv \\!* ~/.Trash"
bash$ junk() { mv "$@" ~/.Trash/; }
Or:
bash$ junk() { for item in "$@" ; do echo "Trashing: $item" ; mv "$item" ~/.Trash/; done; }
其他回答
下面是我的~/.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
}
参考文献:
从字符串中删除空白:如何从Bash变量中删除空白?实际换行符:https://stackoverflow.com/a/4296147/2736496别名w/param:https://stackoverflow.com/a/7131683/2736496(这个问题的另一个答案)组氨酸:https://superuser.com/questions/232885/can-you-share-wisdom-on-using-histignore-in-bashY/N提示:https://stackoverflow.com/a/3232082/2736496从历史记录中删除所有匹配项:https://unix.stackexchange.com/questions/57924/how-to-delete-commands-in-history-matching-a-given-string字符串是否为空:http://tldp.org/LDP/abs/html/comparison-ops.html
要具体回答有关创建别名以将文件移动到垃圾箱文件夹而不是删除文件的问题,请执行以下操作:
alias rm="mv "$1" -t ~/.Trash/"
当然,你必须先创建dir~/.Trash。
然后只需发出以下命令:
$rm <filename>
$rm <dirname>
实际上,函数几乎总是答案,正如手册页中的这句话所证实的:“对于几乎所有的目的,别名都被shell函数所取代。”
为了完整性,并且因为这可能是有用的(稍微更轻量级的语法),可以注意到,当参数跟随别名时,仍然可以使用它们(尽管这不能满足OP的要求)。这可能最容易用一个例子来演示:
alias ssh_disc='ssh -O stop'
允许我键入smth,如ssh_disc myhost,它按预期扩展为:ssh-O stop myhost
这对于接受复杂参数的命令很有用(我的记忆不再是以前的样子了…)
有一次我做了一些有趣的项目,我仍然在使用它。它显示了一些动画,而我通过cp命令复制文件,因为cp没有显示任何内容,这有点令人沮丧。所以我取了这个别名
alias cp="~/SCR/spiner cp"
这是spiner脚本
#!/bin/bash
#Set timer
T=$(date +%s)
#Add some color
. ~/SCR/color
#Animation sprites
sprite=( "(* ) ( *)" " (* )( *) " " ( *)(* ) " "( *) (* )" "(* ) ( *)" )
#Print empty line and hide cursor
printf "\n${COF}"
#Exit function
function bye { printf "${CON}"; [ -e /proc/$pid ] && kill -9 $pid; exit; }; trap bye INT
#Run our command and get its pid
"$@" & pid=$!
#Waiting animation
i=0; while [ -e /proc/$pid ]; do sleep 0.1
printf "\r${GRN}Please wait... ${YLW}${sprite[$i]}${DEF}"
((i++)); [[ $i = ${#sprite[@]} ]] && i=0
done
#Print time and exit
T=$(($(date +%s)-$T))
printf "\n\nTime taken: $(date -u -d @${T} +'%T')\n"
bye
看起来像这样
循环动画)
这里是上面提到的彩色脚本的链接。和新的动画周期)
有正当的技术理由想要一个通用的解决方案来解决bash别名不具有重新定位任意参数的机制的问题。其中一个原因是,您希望执行的命令是否会受到执行函数所导致的环境更改的不利影响。在所有其他情况下,应使用函数。
最近迫使我尝试解决这个问题的是,我想创建一些简短的命令来打印变量和函数的定义。所以我为此写了一些函数。但是,有些变量是(或可能)由函数调用本身更改的。其中包括:
函数名称BASH_源巴什利诺BASH_ARGCBASH_ARGV
我一直在使用的基本命令(在函数中)来打印变量defns。set命令输出的形式为:
sv () { set | grep --color=never -- "^$1=.*"; }
例如。:
> V=voodoo
sv V
V=voodoo
问题:这不会打印上面提到的变量的定义,因为它们在当前上下文中,例如,如果在交互式shell提示符中(或不在任何函数调用中),FUNCNAME没有定义。但我的函数告诉我错误的信息:
> sv FUNCNAME
FUNCNAME=([0]="sv")
我提出的一个解决方案已经在其他关于这个主题的帖子中被提及。对于打印变量defns.的特定命令。,这只需要一个论点,我这样做了:
alias asv='(grep -- "^$(cat -)=.*" <(set)) <<<'
给出正确的输出(无)和结果状态(假):
> asv FUNCNAME
> echo $?
1
然而,我仍然觉得有必要找到一个适用于任意数量的论点的解决方案。
向Bash别名命令传递任意参数的通用解决方案:
# (I put this code in a file "alias-arg.sh"):
# cmd [arg1 ...] – an experimental command that optionally takes args,
# which are printed as "cmd(arg1 ...)"
#
# Also sets global variable "CMD_DONE" to "true".
#
cmd () { echo "cmd($@)"; declare -g CMD_DONE=true; }
# Now set up an alias "ac2" that passes to cmd two arguments placed
# after the alias, but passes them to cmd with their order reversed:
#
# ac2 cmd_arg2 cmd_arg1 – calls "cmd" as: "cmd cmd_arg1 cmd_arg2"
#
alias ac2='
# Set up cmd to be execed after f() finishes:
#
trap '\''cmd "${CMD_ARGV[1]}" "${CMD_ARGV[0]}"'\'' SIGUSR1;
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# (^This is the actually execed command^)
#
# f [arg0 arg1 ...] – acquires args and sets up trap to run cmd:
f () {
declare -ag CMD_ARGV=("$@"); # array to give args to cmd
kill -SIGUSR1 $$; # this causes cmd to be run
trap SIGUSR1; # unset the trap for SIGUSR1
unset CMD_ARGV; # clean up env...
unset f; # incl. this function!
};
f' # Finally, exec f, which will receive the args following "ac2".
例如。:
> . alias-arg.sh
> ac2 one two
cmd(two one)
>
> # Check to see that command run via trap affects this environment:
> asv CMD_DONE
CMD_DONE=true
这个解决方案的一个优点是,在编写被捕获的命令时,所有用于处理命令的位置参数(参数)的特殊技巧都将发挥作用。唯一的区别是必须使用数组语法。
例如。,
如果需要“$@”,请使用“${CMD_ARGV[@]}”。
如果需要“$#”,请使用“${#CMD_ARGV[@]}”。
Etc.