创建不完整命令的别名

创建不完整命令的别名

tldp.org 的文档并没有真正指定 bash 解释器何时或如何替换别名字符串。我正在寻找有关如何创建不完整命令别名的信息。

alias quickscp="scp a.really.long.internal.domain.name:"
quickscp/data/testfile ./testfile

这失败了 - 看起来 bash 不会扩展,testalias除非它匹配一个周围有空格(我假设包括 ^/$)的字符串。

如果别名可以承担 C 预处理器的一些功能(例如宏扩展),那就太好了。

http://tldp.org/LDP/abs/html/aliases.html同意我的观点 - “如果这样就好了”意味着它不像 C 预处理器那样工作。有什么办法可以强制执行吗?上面的 scp 案例中的某些特定内容可以解决我的问题,但我有兴趣知道是否有办法获得我试图实现的逻辑(以备将来黑客攻击)。

我想这可以被概括为:如果别名没有被空格包围,如何让 bash 扩展它?

答案1

在 Bash 别名的定义中它是一个单独的词(参见手册)。我认为你想要的是一个 shell 函数:

quickscp () {
  if [[ "$#" -ne 2 ]]; then echo "Need two arguments"; return 1; fi
  scp host.example.com:"$1" "$2"
  return "$?"
}

像这样称呼它:

quickscp source target

作为奖励,您可以进行参数检查并获得命令的返回代码scp,因此您可以执行quickscp foo bar && echo "yay"或类似的命令链接。

答案2

我认为您不能使用别名来执行此操作。函数怎么样?

unalias quickscp
quickscp () (
   first="$1"
   shift
   exec scp "a.really.long.internal.domain.name:$first" "$@"
)

笔记:

  • unalias因为函数的可移植定义可能与已定义的别名发生冲突。
  • 函数体被刻意放置在子shell中,以使变量名为firstlocal,而没有不可移植的local first语句。
  • exec因为启动后我们不再需要子shell scp

一种完全不同的方法是在 SSH 配置中定义主机(全局:/etc/ssh/ssh_config;用户特定~/.ssh/config:):

Host foo
Hostname a.really.long.internal.domain.name

然后像这样继续:

scp foo:/data/testfile ./testfile

这将与ssh或一起使用scp。它与 shell 中的别名无关。

答案3

我知道的一个技巧是使用空字符串作为扩展的分隔符:

quickscp""/data/testfile ./testfile

相关内容