为什么历史需要 grep 的数值?
Why does history require a numeric value for grep?
我正在尝试创建一个自定义函数 (hisgrep) 以从历史记录中进行 grep。
我以前用过它,当时代码基本上是 "history | grep ",但我希望实现能够 grep 多个关键字。 (例如 "hisgrep docker client" 等于 "history | grep docker | grep client")。
我的问题是,当我尝试执行此操作时出现此错误:“-bash:历史记录:|:需要数字参数。”
我试过将命令的调用方式从 $cmd
更改为仅 $cmd,但没有任何效果。
代码如下:
#!/bin/bash
function hisgrep() {
cmd='history'
for arg in "$@"; do
cmd="$cmd | grep $arg"
done
`$cmd`
}
它不起作用,因为 |
被解释为 history
命令的参数。
遗憾的是,bash 没有所谓的 "foldl" 或类似功能。
你可以这样做:
histgrep() {
local str;
# save the history into some list
# I already filter the first argument, so the initial list is shorter
str=$(history | grep -e "");
shift;
# for each argument
for i; do
# pass the string via grep
str=$(<<<"$str" grep "$i")
done
printf "%s\n" "$str"
}
备注:
- 执行
cmd="$cmd | grep $arg"
然后执行 `$cmd` 看起来不安全。
- 记得引用你的变量。
- 使用 https://www.shellcheck.net/ 检查您的脚本。
- 反引号 ` 是 deprecated。使用
$()
命令替换。
- 同时使用函数和括号
function func()
不可移植。就做 func()
.
至于不安全的版本,您需要通过 eval 传递它(eval
是 evil
),通过智能使用 printf
缩短为:
histgrep() { eval "history $(printf "| grep -e '%s' " "$@")"; }
但我认为我们可以通过在 eval
调用中扩展命令替换后的参数来做一些更安全的事情:
histgrep() { eval "history $(printf '| grep -e "$%s" ' $(seq $#))"; }
这里的eval
会看到history | grep -e "" | grep -e "" | ...
我觉得其实挺安全的
我正在尝试创建一个自定义函数 (hisgrep) 以从历史记录中进行 grep。
我以前用过它,当时代码基本上是 "history | grep ",但我希望实现能够 grep 多个关键字。 (例如 "hisgrep docker client" 等于 "history | grep docker | grep client")。
我的问题是,当我尝试执行此操作时出现此错误:“-bash:历史记录:|:需要数字参数。”
我试过将命令的调用方式从 $cmd
更改为仅 $cmd,但没有任何效果。
代码如下:
#!/bin/bash
function hisgrep() {
cmd='history'
for arg in "$@"; do
cmd="$cmd | grep $arg"
done
`$cmd`
}
它不起作用,因为 |
被解释为 history
命令的参数。
遗憾的是,bash 没有所谓的 "foldl" 或类似功能。
你可以这样做:
histgrep() {
local str;
# save the history into some list
# I already filter the first argument, so the initial list is shorter
str=$(history | grep -e "");
shift;
# for each argument
for i; do
# pass the string via grep
str=$(<<<"$str" grep "$i")
done
printf "%s\n" "$str"
}
备注:
- 执行
cmd="$cmd | grep $arg"
然后执行 `$cmd` 看起来不安全。 - 记得引用你的变量。
- 使用 https://www.shellcheck.net/ 检查您的脚本。
- 反引号 ` 是 deprecated。使用
$()
命令替换。 - 同时使用函数和括号
function func()
不可移植。就做func()
.
至于不安全的版本,您需要通过 eval 传递它(eval
是 evil
),通过智能使用 printf
缩短为:
histgrep() { eval "history $(printf "| grep -e '%s' " "$@")"; }
但我认为我们可以通过在 eval
调用中扩展命令替换后的参数来做一些更安全的事情:
histgrep() { eval "history $(printf '| grep -e "$%s" ' $(seq $#))"; }
这里的eval
会看到history | grep -e "" | grep -e "" | ...
我觉得其实挺安全的