Bash 将任意命令通过管道传递给 less 的别名
Bash alias to pipe an arbitrary command to less
简而言之shell 我正在努力让 Perforce 工作起来更少。目前,诸如 p4 diff
之类的命令会愉快地将 5000 行转储到控制台。我希望像这样的命令能够自动输入 less 而无需我输入它(你知道,就像 g*t 那样)。
我目前最好的两个"solutions":
"Solution" 1 - A bash 函数
function p4() {
pager=""
if [ "" = "diff" ]
then
pager=" | less"
fi
/bin/sh -c "/usr/local/bin/p4 "$@" $pager"
}
问题在于 Perforce 语法与 Unix shell 语法重叠。
即 p4 jobs ...@\>2015/01/20
会因为 >
符号而严重失败。
"Solution" 2 - 具有不同名称的函数
function p4d() {
p4 diff "$@" | less
}
这很蹩脚,因为现在我必须记住键入 p4d
而不是 p4 diff
,并且出于与解决方案 1 相同的原因,不适用于 p4 diff2
。
是否有任何 shell 或 Perforce 技巧可以让我使用 p4 diff
之类的命令通过管道传输到 less
而无需记住一直输入它?
有没有一种方法可以安全地包装 p4
参数 ($@
),这样 shell 像 >
这样的符号就不会被重新解释,而是 |
是?
不必是 bash。如果你有一些来自 60 年代的时髦 shell 解决了我的问题,让我们听听吧!
感谢您的帮助。
Eval 类型的解决方案通常不能很好地应对其中包含奇数字符的参数。另一方面,它们通常是不必要的。
而不是
/bin/sh -c "/usr/local/bin/p4 "$@" $pager"
有引号错误($@
周围的引号实际上未引号 $@
尽管修复它无济于事,因为您实际上需要在传递给 [=19 的字符串中插入转义符=]),直接执行命令即可:
/usr/local/bin/p4 "$@" | "$pager"
需要定义$pager
;你可能想要:
if [[ $pager ]]; then
/usr/local/bin/p4 "$@" | "$pager"
else
/usr/local/bin/p4 "$@"
fi
显式路径有点烦人。使用 bash,您可以使用 command
内置函数使它更健壮:
if [[ $pager ]]; then
command p4 "$@" | "$pager"
else
command p4 "$@"
fi
这引入了少量的重复代码,如果您要在不同的地方使用被截断的代码,那么它会有点多。您可以定义以下函数(例如,在您的 ~/.bashrc
文件中):
page() {
if [[ $pager ]]; then
"$@" | "${pager[@]}"
else
"$@"
fi
}
那么您的 p4
脚本可以是:
p4() {
local pager=
if [[ = diff ]]; then pager=less; fi
page command p4 "$@"
}
还有很多其他变体。注意在page
函数中使用"${pager[@]}"
;这允许 pager
成为一个数组,以防你想将参数传递给 less。例如:
( pager=(less -N); p4 diff ...; )
(括号是为了使 pager
的设置成为局部的;您不能对数组使用正常的 var=value command
语法。)
我对如何实现 p4
功能的建议:
function p4() {
if [[ == diff ]]; then
command p4 "$@" | less
else
command p4 "$@"
fi
}
这将消除您遇到的引用和转义问题。
如果管道连接到 cat
没问题,您可以消除重复的 command p4 "$@"
部分(当 stdout 连接到 TTY 和管道时,某些命令的行为会有所不同;我不知道是否强制关心):
function p4() {
command p4 "$@" | if [[ == diff ]]; then less; else cat; fi
}
简而言之shell 我正在努力让 Perforce 工作起来更少。目前,诸如 p4 diff
之类的命令会愉快地将 5000 行转储到控制台。我希望像这样的命令能够自动输入 less 而无需我输入它(你知道,就像 g*t 那样)。
我目前最好的两个"solutions":
"Solution" 1 - A bash 函数
function p4() {
pager=""
if [ "" = "diff" ]
then
pager=" | less"
fi
/bin/sh -c "/usr/local/bin/p4 "$@" $pager"
}
问题在于 Perforce 语法与 Unix shell 语法重叠。
即 p4 jobs ...@\>2015/01/20
会因为 >
符号而严重失败。
"Solution" 2 - 具有不同名称的函数
function p4d() {
p4 diff "$@" | less
}
这很蹩脚,因为现在我必须记住键入 p4d
而不是 p4 diff
,并且出于与解决方案 1 相同的原因,不适用于 p4 diff2
。
是否有任何 shell 或 Perforce 技巧可以让我使用 p4 diff
之类的命令通过管道传输到 less
而无需记住一直输入它?
有没有一种方法可以安全地包装 p4
参数 ($@
),这样 shell 像 >
这样的符号就不会被重新解释,而是 |
是?
不必是 bash。如果你有一些来自 60 年代的时髦 shell 解决了我的问题,让我们听听吧!
感谢您的帮助。
Eval 类型的解决方案通常不能很好地应对其中包含奇数字符的参数。另一方面,它们通常是不必要的。
而不是
/bin/sh -c "/usr/local/bin/p4 "$@" $pager"
有引号错误($@
周围的引号实际上未引号 $@
尽管修复它无济于事,因为您实际上需要在传递给 [=19 的字符串中插入转义符=]),直接执行命令即可:
/usr/local/bin/p4 "$@" | "$pager"
需要定义$pager
;你可能想要:
if [[ $pager ]]; then
/usr/local/bin/p4 "$@" | "$pager"
else
/usr/local/bin/p4 "$@"
fi
显式路径有点烦人。使用 bash,您可以使用 command
内置函数使它更健壮:
if [[ $pager ]]; then
command p4 "$@" | "$pager"
else
command p4 "$@"
fi
这引入了少量的重复代码,如果您要在不同的地方使用被截断的代码,那么它会有点多。您可以定义以下函数(例如,在您的 ~/.bashrc
文件中):
page() {
if [[ $pager ]]; then
"$@" | "${pager[@]}"
else
"$@"
fi
}
那么您的 p4
脚本可以是:
p4() {
local pager=
if [[ = diff ]]; then pager=less; fi
page command p4 "$@"
}
还有很多其他变体。注意在page
函数中使用"${pager[@]}"
;这允许 pager
成为一个数组,以防你想将参数传递给 less。例如:
( pager=(less -N); p4 diff ...; )
(括号是为了使 pager
的设置成为局部的;您不能对数组使用正常的 var=value command
语法。)
我对如何实现 p4
功能的建议:
function p4() {
if [[ == diff ]]; then
command p4 "$@" | less
else
command p4 "$@"
fi
}
这将消除您遇到的引用和转义问题。
如果管道连接到 cat
没问题,您可以消除重复的 command p4 "$@"
部分(当 stdout 连接到 TTY 和管道时,某些命令的行为会有所不同;我不知道是否强制关心):
function p4() {
command p4 "$@" | if [[ == diff ]]; then less; else cat; fi
}