
私はこれについて Google で検索し、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
次のようにすると、まったく同じ動作になります。
マイスクリプト:
#!/usr/bin/env sh
gzip
cat ファイル | ./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
標準入力から非圧縮データを読み取り、標準出力に圧縮データを書き込みます。
標準入力はパイプによって提供され、標準出力はファイルにリダイレクトされます。パイプとリダイレクトは、呼び出し元のシェルによって処理されます。
sed
コマンドラインで式を受け取り、それに従って入力を変換するか、式が使用されなかった場合はデータを転送するだけの、もう少し複雑な例です。
#!/bin/sh
if [ -n "$1" ]; then
sed -e "$1"
else
cat
fi
(ここで を使用するとsed -e ""
と同じ効果が得られますcat
が、より複雑な例が欲しかったのです)
$ utility | ./script "1,5d" >out
... は、出力の最初の 5 行を削除しますutility
。
答え2
複雑な状況をより単純な例で説明しようとしているため、スクリプトのどの部分が単純な誤解で、どの部分が複雑なのかわかりません。
そうは言っても、これはあなたの質問が求めていることを実行します:
#!/bin/sh
gzip "$@"
答え3
を使用し、入力の一部を読み取って空かどうかを確認するには、次のように変数に任意のバイト値を格納できるよう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