Linux
如何使用 ‘watch’ 命令將多個也帶有引號(“)的命令括起來?
我想將該
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\.
轉義它或-F
ingrep
或index()
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
選項。