簡體   English   中英

為什么歷史記錄要求grep使用數字值?

[英]Why does history require a numeric value for grep?

我試圖做一個自定義功能(hisgrep)來從歷史grep。

我以前曾經工作過,當時代碼基本上是“ history | grep $ 1”,但是我希望實現能夠grep多個關鍵字。 (例如,“ hisgrep docker客戶”將等於“歷史| grep docker | grep客戶”)。

我的問題是,當我嘗試執行此操作時,出現以下錯誤:“-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 "$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傳遞它(而evalevil ),通過使用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" | ... history | grep -e "$1" | grep -e "$2" | ... history | grep -e "$1" | grep -e "$2" | ...我認為實際上看起來很安全。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM