如何通過 shell 腳本將標題行注入管道?
我正在研究通過管道將數據從一台伺服器發送到另一台伺服器進行處理的過程。
雖然這不是確切的命令,但它可能看起來像這樣:
tail -f logfile | grep "abc" | grep "def" | grep -v "ghi" | netcat -q 0 n.n.n.n 7777
我想將所有這些 grep 包裝到一個腳本中,更重要的是在管道前面加上
netcat
一個標識符,所以命令看起來像這樣:tail -f logfile | myscript.sh {id}
在另一端監聽的腳本應該收到:
{id} [Line 1 of the logfile] [Line 2 of the logfile] ...
將其包裝在腳本中很容易:
#!/bin/sh id=$1 grep "abc" | grep "def" | grep -v "ghi" | netcat -q 0 n.n.n.n 7777
但我不知道如何
$id
在一開始注入。接收端正在使用
socat -u tcp-l:7777,fork system:/dev/receivePipe
因此,如果有不同的方式我可以獲取 id(例如以某種方式作為參數
/dev/receivePipe
),或者通過環境變數,那也可以。編輯:最終答案在已接受答案的評論中得出:
#!/bin/sh { printf '%s\n' $1 grep "abc" | grep "def" | grep -v "ghi" } | netcat -q 0 192.168.56.105 7777
做就是了:
#! /bin/sh - { printf '%s\n' "${1-default-id}" awk '/abc/ && /def/ && ! /ghi/' } | socat - tcp:n.n.n.n:7777
${1-default-id}
如果指定或以其他方式擴展至第一個位置參數default-id
。如果未傳遞任何參數,則替換為${1?}
以錯誤退出(或${1?The error message}
指定錯誤消息而不是預設值)。我們將執行
printf
以輸出 ID 和過濾命令grep
的命令組的輸出重定向awk
到socat
/netcat
。或者僅在讀取並匹配一行時列印 ID:
#! /bin/sh - ID=${1-default-id} awk ' /abc/ && /def/ && ! /ghi/ { if (!already_printed++) print ENVIRON["ID"] print }' | socat - tcp:n.n.n.n:7777
或者將 ID(和空格字元)添加到每一行:
#! /bin/sh - ID=${1-default-id} awk ' /abc/ && /def/ && ! /ghi/ { print ENVIRON["ID"], $0 }' | socat - tcp:n.n.n.n:7777
當心,當輸出到管道(到 tty 設備以外的任何設備)時
awk
,like會緩衝它們的輸出。使用(aka )grep
的 GNU 實現,您可以在每個之後添加一個呼叫來強制刷新該緩衝區。另見的。在大多數實現中,執行 a也會強制刷新。的 GNU 實現可以選擇在每行輸出後強制刷新。awk``gawk``fflush()``print``-Winteractive``mawk``awk``system("")``grep``--line-buffered
另請注意,它
tail -f logfile
是tail -n 10 -f logfile
. 您實際上可能希望tail -n +1 -f logfile
處理整個日誌文件,然後繼續處理該文件,或者只處理從現在tail
開始添加的行。f``tail -n 0 -f logfile