如何將輸出通過管道傳輸到 sh 腳本並將其通過管道傳輸到命令?

如何將輸出通過管道傳輸到 sh 腳本並將其通過管道傳輸到命令?

我一直在谷歌上搜索這個並蒐索 Stack,但沒有找到我想要做的確切事情。我真的還不能理解這個問題。

所以,假設我有 sh 腳本,它只是 gzip 的包裝器(僅作為示例)。在命令列上,我想將某些內容(例如mysqldump)的輸出透過管道傳輸到我的腳本。然後,該腳本必須獲取輸入並將其通過管道傳輸到 gzip。

命令列範例:

mysqldump somedb | mysqldump somedb | myscript > somefile.dmp.gz

myscript 的範例(我嘗試過的):

#!/usr/bin/env sh
read inp
command="echo \"$inp\" | gzip"
eval $command

這個例子可能有很多問題。請幫忙? :)

解決方案(供其他人尋找)

感謝下面的解釋,我現在明白在 SH 腳本中執行命令將簡單地將輸入通過管道傳輸到腳本,就像直接執行命令時一樣。

所以在這種情況下:

貓檔案|壓縮包

將執行與以下完全相同的操作:

我的腳本:

#!/usr/bin/env sh
gzip

貓檔案| ./myscript

所以我想指出,就我而言,還有另一個問題:在我的現實世界腳本中,我嘗試透過以下讀取來檢查是否存在輸入流:

read inp
if [ -z "$inp" ]; then
    echo "No input"
    exit;
fi

事實證明,在 後read inp,輸入管道是空的。

答案1

#!/bin/sh
gzip -c

這就足夠了。

$ mysqldump ... | ./script >out.gz

gzip -c將在其標準輸入上讀取未壓縮的資料並將壓縮的資料寫入其標準輸出。

標準輸入由管道提供,標準輸出重定向到檔案。管道和重定向由呼叫 shell 負責。

一個稍微複雜的範例,它將sed在命令列上採用表達式並根據該表達式轉換輸入,或者如果未使用表達式則僅轉送資料:

#!/bin/sh

if [ -n "$1" ]; then
    sed -e "$1"
else
    cat
fi

(在這裡,使用sed -e ""與 具有相同的效果cat,但我想要一個更複雜的範例)

$ utility | ./script "1,5d" >out

...將從 中刪除前五行輸出utility

答案2

我不確定你的腳本的哪一部分是簡單的誤解,哪一部分是複雜的,因為你試圖用一個更簡單的例子來說明複雜的情況。

話雖如此,這將滿足您的問題要求:

#!/bin/sh
gzip "$@"

答案3

要使用read, 讀取一些輸入來檢查它是否為空,您必須使用這樣的 shell,zsh可以在其變數中儲存任何位元組值,例如:

#! /bin/zsh -
if LC_ALL=C read -ru0 -k1 byte; then
  # one byte was read, the input is not empty
  (printf %s "$byte"; cat) | gzip
else
  echo >&2 No input
fi

或使用某種形式的編碼:

#! /bin/sh -
# get the value of the first byte as octal:
byte=$(od -An -N1 -vto1 | tr -cd 0-7)

if [ -n "$byte" ]; then
  (printf "\\$byte"; cat) | gzip
else
  echo >&2 No input
fi

相關內容