我使用 LINUX (ubuntu 14) 我新购买的笔记本电脑迫使我使用 shell bash
,它有.bashrc
.在此之前我曾经使用过 C-shell,并尝试通过一些明显的编辑将其别名从 复制.cshrc
到。.bashrc
但有一件事不起作用——延迟论证。举个例子 - 我的.cshrc
命令:
alias rm 'mv -f \!* $HOME/zap'
当在 .bshrc 中写为
alias rm = 'mv -f \!* $HOME/zap'
生成错误消息:
bash:alias: rm: not found
bash:alias: mv -f \!* $HOME/zap: not found
(该目录zap
是我提前创建的)
我应该用什么来代替\!*
?
答案1
在这些情况下,您应该使用 shell 函数而不是别名。键入的内容较多,但可以让您更加灵活:
function rm {
if ! test -d "$HOME/zap"; then
echo "No zap in home" >&2
return 1
else
mv -f -- "$@" "$HOME/zap/"
fi
}
将扩展为您在命令行上$@
给出的参数。rm
有--
必要发出命令行标志结束的信号(这样rm -f
,where-f
是一个文件,是可能的,rm
并且mv
无论如何都不共享许多命令行标志)。
要访问原始rm
命令,请使用\rm
或command rm
。
测试是否存在$HOME/zap
、向标准错误输出错误消息以及在函数中以非零退出状态退出只是为了表明您可以在其中执行任何您想要的操作。显然你可以将其简化为
function rm {
mv -f -- "$@" "$HOME/zap/"
}
该bash
手册包含以下声明:
对于几乎所有用途,别名都被 shell 函数取代。
别名实际上只对例如标记您最喜欢的标志ls
以及类似的事情有用。
答案2
如果删除不需要的空格,该命令将有一定的工作希望:
$ alias rm='mv -f \!* $HOME/zap'
让我们添加一个回显来“查看”在不移动文件的情况下发生的情况:
$ alias rm='echo mv -f \!* $HOME/zap'
$ rm one two three
mv -f !* /home/immf/zap one two three
这只是表明 bash 历史记录的工作方式与csh
历史命令不同,因为 csh 使用:
如果别名包含历史引用,它将经历历史替换,就好像原始命令是上一个输入行一样。
而 bash 则不然。更重要的是,bash 别名有以下限制:
没有在替换文本中使用参数的机制。如果需要参数,则应使用 shell 函数。
当 shell 不具有交互性时,别名不会扩展。
也就是说:无法重用当前行中的参数,而且别名在脚本中不起作用(默认情况下)。
但是,别名的目的是重复使用相同的参数并添加最后一个目录作为文件移动的目标:
$ alias rm 'echo mv -f \!* $HOME/zap' ### in csh
$ rm one two 333 ### in csh
mv -f one two 333 /home/user/zap
这可以通过-t
以下选项轻松完成mv
(在 bsd 中不可用mv
):
$ alias rm='echo mv -f -t "$HOME/zap"'
$ rm one two 333
mv -f -t /home/user/zap one two 333
简而言之:使用函数是明智的。