私はこれをグーグルで検索してStackを検索しましたが、やりたいことを正確に見つけることができませんでした。私はまだこれに頭を悩ませることはできません。
それで、gzipのラッパーにすぎないshスクリプトがあるとしましょう(例として)。コマンドラインで、何かの出力(たとえば、mysqldump
)をスクリプトにパイプします。次に、そのスクリプトは入力を受け取り、それをgzipにパイプする必要があります。
コマンドラインの例:
mysqldump somedb | myscript> somefile.dmp.gz
Myscriptの例(私が試したもの):
#!/usr/bin/env sh
read inp
command="echo \"$inp\" | gzip"
eval $command
おそらく、この例では多くのことが間違っています。助けてください? :)
解決策(それを探している他の人のために)
以下の説明のおかげで、SHスクリプトでコマンドを実行すると、コマンドが直接実行されたときだけでなく、スクリプトにパイプされた入力も単純に取得されることがわかりました。
したがって、この場合:
catファイル| gzip
次とまったく同じように動作します。
myscript:
#!/usr/bin/env sh
gzip
catファイル| ./myscript
したがって、私の場合は別の問題もあったことを指摘したいと思います。実際のスクリプトでは、次のように読んで、入力ストリームがあるかどうかを確認しようとしました。
read inp
if [ -z "$inp" ]; then
echo "No input"
exit;
fi
read inp
の後、入力パイプが空であることがわかります。
#!/bin/sh
gzip -c
それで十分でしょう。
$ mysqldump ... | ./script >out.gz
gzip -c
は、標準入力で非圧縮データを読み取り、圧縮データを標準出力に書き込みます。
標準入力はパイプによって提供され、標準出力はファイルにリダイレクトされます。パイプとリダイレクトは、呼び出し元のシェルによって処理されます。
コマンドラインでsed
式を取り、それに応じて入力を変換する、または式が使用されていない場合はデータを転送する、もう少し複雑な例:
#!/bin/sh
if [ -n "$1" ]; then
sed -e "$1"
else
cat
fi
(ここでは、sed -e ""
を使用するとcat
と同じ効果がありますが、もっと複雑な例が必要でした)
$ utility | ./script "1,5d" >out
...は、出力の最初の5行をutility
から削除します。
スクリプトのどの部分が単純な誤解であり、どの部分が複雑であるかはわかりません。これは、より単純な例で複雑な状況を説明しようとしているためです。
そうは言っても、これはあなたの質問が尋ねることをします:
#!/bin/sh
gzip "$@"
read
を使用し、入力の一部を読み取って空かどうかを確認するには、次のような変数に任意のバイト値を格納できる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