Linux

如何使用 ‘watch’ 命令將多個也帶有引號(“)的命令括起來?

  • October 10, 2021

我想將該watch命令用於以下命令鏈:

journalctl | grep 'UFW BLOCK' | grep 'DST=192.168.0.2' | awk '{printf "%-4s%-3s%-10s%-1s%+16s\n", $1, $2, $3, $7, $11, $18, $19}'

通常,當我想應用於watch命令鏈時,我會將鏈括在引號之間

watch "COMMAND_1 | COMMAND_2 | ... | COMMAND_n"

但是當上面的命令之一中有另一個引號時,它會出錯。這個問題的解決方法是什麼?

為避免擔心引號,您可以使用此處的文件:

shell_code=$(cat << 'EOF'
 journalctl |
   awk '
     /UFW BLOCK/ && index($0, "DST=192.168.0.2 ") {
        printf "%-4s%-3s%-10s%-1s%+16s\n", $1, $2, $3, $7, $11, $18, $19
     }'
EOF
)

watch "$shell_code"

(或者watch sh -c "$shell_code"如果您的watch實現尚未啟動 shell 來解釋命令行而是執行命令本身,儘管這些watch實現現在變得越來越少了¹)。

其他一些注意事項:

  • awk可以做大部分grep可以做的事情,所以你很少需要把它們放在一起。
  • .是匹配任何單個字元的正則表達式運算符。grep 192.168.0.2將匹配在192.168.012. 您可以使用[.]or\.轉義它或-Fingrepindex()inawk進行子字元串搜尋,而不是正則表達式匹配。
  • 如果您不在搜尋字元串中添加額外的空格,您也會DST=192.168.0.2在其中找到DST=192.168.0.234。使用grep -Fw DST=192.168.0.2將解決這兩個問題。
  • 我會避免用雙引號括住 shell 程式碼,因為很容易忘記轉義$s 或```s 並引入命令注入漏洞(變數的內容可能被解釋為 shell 程式碼)。單引號更安全,因為您可以保證其中沒有特殊字元。由於這包括's 本身(至少在類似 Bourne 的 shell 中²),這意味著您不能在's 內包含 s '...',但您始終可以將它們輸入為'foo'\''bar',它'foo'\''用反斜杠引用)與'bar'. 所以在這裡:
watch 'journalctl |
  awk '\''
    /UFW BLOCK/ && index($0, "DST=192.168.0.2 ") {
       printf "%-4s%-3s%-10s%-1s%+16s\n", $1, $2, $3, $7, $11, $18, $19
    }'\'
  • journalctl有一個-f/--follow模式,其中新的日誌條目在到達時顯示。您可能想要使用它,而不是一遍又一遍地搜尋完整的日誌。

¹執行中的watch實現以使用空格連接其參數來解釋程式碼,但可以使用/選項直接執行命令,從而讓您更輕鬆地讓其他語言解釋器(如or )解釋程式碼。procps-ng``sh``-x``--exec``watch -x zsh -c 'zsh code'``watch -x perl -e 'perl code'

² 雖然為了完整性,zsh(類似 Bourne;雖然也具有 rc 和 csh 的功能)可以'foo''bar'在單引號字元串中使用單引號,rc如果您啟用該rcquotes選項。

引用自:https://unix.stackexchange.com/questions/672589