Почему история требует числовое значение для grep? - PullRequest
0 голосов
/ 06 июня 2019

Я пытаюсь создать пользовательскую функцию (hisgrep) для извлечения из истории.

У меня она работала раньше, когда код был в основном "history | grep $ 1", но я хочу, чтобы реализация былавозможность поиска нескольких ключевых слов.(например, «isgrep docker client» будет равен «history | grep docker | grep client»).

Моя проблема в том, что, когда я пытаюсь сделать это, я получаю эту ошибку: "-bash: history: |:требуется числовой аргумент. "

Я попытался изменить способ вызова команды в конце с $cmd до $ cmd, но это ничего не дало.

Вот код:

#!/bin/bash

function hisgrep() {
    cmd='history'
    for arg in "$@"; do
        cmd="$cmd | grep $arg"
    done
    `$cmd`
}

Ответы [ 2 ]

1 голос
/ 06 июня 2019

К сожалению, 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 "$1");
    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/ для проверки ваших сценариев.
  • Обратные пометки ` устарели . Используйте $() подстановку команд.
  • с использованием функции и скобок 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 "$1" | grep -e "$2" | ..., который, я думаю, выглядит вполне безопасным.

1 голос
/ 06 июня 2019

Не работает, потому что | интерпретируется как аргумент команды history.

...