Bash

如何檢查管道是否為空,如果不是則對數據執行命令?

  • February 6, 2022

我在 bash 腳本中通過管道傳輸了一行,並想在將管道輸入到程序之前檢查管道是否有數據。

搜尋我發現test -t 0但它在這裡不起作用。總是返回假。那麼如何確定管道有數據呢?

例子:

echo "string" | [ -t 0 ] && echo "empty" || echo "fill"

輸出:fill

echo "string" | tail -n+2 | [ -t 0 ] && echo "empty" || echo "fill"

輸出:fill

測試上述管道是否產生輸出的標準/規範方式不同?需要保留輸入以將其傳遞給程序。這概括瞭如何將輸出從一個程序傳送到另一個程序,但只有在第一個程序有輸出時才執行?它專注於發送電子郵件。

沒有辦法使用常用的 shell 實用程序來查看管道的內容,也沒有辦法從管道中讀取一個字元然後放回它。知道管道有數據的唯一方法是讀取一個字節,然後你必須將該字節送到它的目的地。

所以就這樣做:讀取一個字節;如果檢測到文件結尾,則在輸入為空時執行您想要執行的操作;如果您確實讀取了一個字節,那麼當輸入不為空時分叉您想要執行的操作,將該字節傳輸到其中,然後傳輸其餘數據。

first_byte=$(dd bs=1 count=1 2>/dev/null | od -t o1 -A n | tr -dc 0-9)
if [ -z "$first_byte" ]; then
 # stuff to do if the input is empty
else
 {
   printf "\\$first_byte"
   cat
 } | {
   # stuff to do if the input is not empty
 }      
fi

Joey Hess 的 moreutils中的ifne實用程序在其輸入不為空時執行命令。它通常不會預設安裝,但它應該可用或易於建構在大多數 unix 變體上。如果輸入為空,則什麼都不做,返回狀態0,不能與命令執行成功區分。如果您想在輸入為空的情況下執行某些操作,則需要安排命令不返回 0,這可以通過讓成功案例返回可區分的錯誤狀態來完成:ifne

ifne sh -c 'do_stuff_with_input && exit 255'
case $? in
 0) echo empty;;
 255) echo success;;
 *) echo failure;;
esac

test -t 0與此無關;它測試標準輸入是否是終端。它並沒有說任何輸入是否可用。

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