
ifne
- 標準入力が空でない場合のコマンド実行
可能であれば、標準入力も空の場合は、コマンドの他の部分を実行したいと思いますifne
。
$ printf "hello" | ifne echo "world"
world
ここでは、標準入力が空の場合は別のステートメントで終わりたいと思います。
$ printf "" | ifne echo "world" || echo "else"
しかし、何も印刷されません。可能else
ですかifne
?
答え1
( ifne -n sh -c 'exec >&3; echo else' | ifne echo world ) 3>&1
標準入力が空でないとifne -n
実行されず、入力が2番目の入力に渡されるsh …
かのように動作します。 2番目が実行されます。とても簡単です。cat
ifne
ifne
echo world
標準入力が空の場合はifne -n
実行されますsh …
。ただ使用することはできませんifne -n echo else | …
。これはelse
2番目の項目に到達し、ifne
それも得ることができるからですworld
。したがって、私たちは3>&1
以前も全体の標準出力にアクセスできます|
。ファイル記述子として使用できます。 3.データがからでなければならないifne -n echo else >&3 | …
null以外の入力の場合を中止します。私たちが望むものを得るにはリダイレクトが必要ですが、リダイレクト自体は必要ありません。ifne -n
ifne
echo
ifne -n
echo else
他のコマンドに置き換えることができます。他のコマンドに置き換えることができます(複数のコマンドが必要な場合がecho word
あります)。sh -c …
私のポイントは、この回答が代替に依存したりelse
印刷されworld
たりしないことです。沈黙することもそうでないかもしれません。それは問題ではありません。
答え2
マニュアルページから:
-n リバース操作です。標準入力が空の場合、コマンドが実行されます。標準入力が空でない場合、この場合はifneを介して渡されます。
$ printf "not-empty\n" | ifne printf "This will print\n"
This will print
$ printf "" | ifne printf "This will not print\n"
$ printf "not-empty\n" | ifne -n printf "This will not print\n"
not-empty
$ printf "" | ifne -n printf "This will print\n"
This will print
これにより、次のことができます。
$ dosoemthing | ifne -n printf "There was no output"
if-then-elseタイプのソリューションを探している場合は、stdoutをtee
can callの2つのインスタンスにパイプできますifne
。
$ printf "if\n" | tee >(ifne printf "then\n") | ifne -n printf "else\n"
if
then
$ printf "" | tee >(ifne printf "then\n") | ifne -n printf "else\n"
else
ただし、生の標準出力を印刷することもできます。そのような過程を経るのですifne -n
。
答え3
既存の回答に加えて、ifne
標準入力から読み取ろうとすることで動作し、何かが来たらコマンドを実行し、パイプループを介してその中にデータを保存します。
ただし、ほとんどの入力タイプでは、入力を読み取らずに入力があるかどうかを検出できるため、インポート処理が節約され、パイプは発生しません。
たとえば、次のように定義できます。
input_available() {
perl -MIO::Poll -e '
$p = IO::Poll->new;
$p->mask(STDIN, POLLIN);
$p->poll or die "poll: $!\n";
exit(1) unless $p->events(STDIN) & POLLIN;
require "sys/ioctl.ph";
$n = pack("L", 0);
ioctl(STDIN, &FIONREAD, $n) or die"ioctl: $!\n";
$n = unpack("L", $n);
exit(1) unless $n > 0'
}
その後、次のことができます。
some-command |
if input_available; then
echo Input available:
cat
else
echo No input available
fi
poll()
Linuxでは、POLLIN
一部のデータが存在する場合にのみパイプに表示が行われますが、一部のシステムではPOLLINでファイルの終わりが表示されるため、すべてのシステムに該当するわけではありません。したがって、FIONREAD ioctlは実際にデータがあるかどうかを確認します。この ioctl はどのタイプの入力でも動作しません。たとえば、Linuxでは機能しないことがわかりました/dev/null
。しかし、少なくとも通常のファイル、パイプ、およびttyデバイスで動作します。
答え4
管路
somecommand | ifne echo something
...標準出力に書き込まれると、出力(文字列something
)が生成されます。somecommand
パイプが出力を生成しない場合、somecommand
出力も生成されません。これは次の方法でキャプチャできますifne -n
。
somecommand | ifne echo something | ifne -n echo nothing
テスト:
$ printf 'ok' | ifne echo something | ifne -n echo nothing
something
$ printf '' | ifne echo something | ifne -n echo nothing
nothing
これにより、パイプラインで一番左のコマンドの出力が削除されます。この問題は、次のようなものを使用して解決できます。
ifne sh -c 'cat;echo something'
...パイプラインの2番目のコマンドで、どのcat
コマンドでも左から出力を受け取る必要があります。
これはまた、最後のコマンドが入力を提供しないのに対し、最初のコマンドは出力を生成しないという事実にも依存します。