使用Bash别名将任意命令传递给less

时间:2015-01-26 14:43:34

标签: bash shell perforce

简而言之,我试图让Perforce更少地工作。目前,诸如p4 diff之类的命令将很乐意将5000行转储到控制台。我想要这样的命令自动管道输入更少而不必我输入它(你知道,就像g * t一样)。

到目前为止,我的两个最好的“解决方案”:

“解决方案”1 - bash功能

function p4() {
    pager=""
    if [ "$1" = "diff" ]
    then
        pager=" | less"
    fi

    /bin/sh -c "/usr/local/bin/p4 "$@" $pager"
}

问题是Perforce语法与Unix shell语法重叠。 因为p4 jobs ...@\>2015/01/20符号,>将会失败。

“解决方案”2 - 具有不同名称的功能

function p4d() {
    p4 diff "$@" | less
}

哪个是蹩脚的,因为现在我必须记住输入p4d而不是p4 diff,并且因为与解决方案1相同的原因而不能用于p4 diff2

我是否可以使用任何shell或Perforce技巧来将p4 diff之类的命令导入less,而不必记住一直输入它?

有没有办法可以安全地包装p4参数($@),以便不重新解释>之类的shell符号,但|是?

不一定是bash。如果你有一些60年代的时髦外壳可以解决我的问题,那就听听吧!

感谢您的帮助。

2 个答案:

答案 0 :(得分:4)

Eval类型解决方案通常无法对其中包含奇数字符的参数进行强健。另一方面,它们通常是不必要的。

而不是

/bin/sh -c "/usr/local/bin/p4 "$@" $pager"

有一个引用错误($@左右的引号实际上是不引用$@,虽然修复它不会有帮助,因为你实际上需要将转义插入传递给{{1的字符串你可以直接执行命令:

bash -c

这要求定义/usr/local/bin/p4 "$@" | "$pager" ;你可能想要:

$pager

显式路径有点烦人。使用bash,您可以使用if [[ $pager ]]; then /usr/local/bin/p4 "$@" | "$pager" else /usr/local/bin/p4 "$@" fi builtin:

使其更加强大
command

这引入了一些小的代码重复,如果您要在各个地方使用剪切代码,它会有点多。您可以定义以下函数(例如,在if [[ $pager ]]; then command p4 "$@" | "$pager" else command p4 "$@" fi 文件中):

~/.bashrc

然后您的page() { if [[ $pager ]]; then "$@" | "${pager[@]}" else "$@" fi } 脚本可能是:

p4

还有很多其他变种。请注意在p4() { local pager= if [[ $1 = diff ]]; then pager=less; fi page command p4 "$@" } 函数中使用"${pager[@]}";这允许page成为一个数组,以防你想将参数传递给less。例如:

pager

(括号用于设置( pager=(less -N); p4 diff ...; ) 本地;您不能对数组使用正常的pager语法。)

答案 1 :(得分:3)

我建议如何实施p4功能:

function p4() {
    if [[ $1 == diff ]]; then
        command p4 "$@" | less
    else
        command p4 "$@"
    fi
}

这将消除您所看到的引用和逃避问题。

如果管道到command p4 "$@"是正常的,你可以消除重复的cat件(当stdout连接到TTY与管道时,某些命令的行为会有所不同;我不知道是否perforce cares):

function p4() {
    command p4 "$@" | if [[ $1 == diff ]]; then less; else cat; fi
}