ifneでelseをどのように使用しますか?

ifneでelseをどのように使用しますか?

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番目が実行されます。とても簡単です。catifneifneecho world

標準入力が空の場合はifne -n実行されますsh …。ただ使用することはできませんifne -n echo else | …。これはelse2番目の項目に到達し、ifneそれも得ることができるからですworld。したがって、私たちは3>&1以前も全体の標準出力にアクセスできます|。ファイル記述子として使用できます。 3.データがからでなければならないifne -n echo else >&3 | …null以外の入力の場合を中止します。私たちが望むものを得るにはリダイレクトが必要ですが、リダイレクト自体は必要ありません。ifne -nifneechoifne -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をteecan 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コマンドでも左から出力を受け取る必要があります。

これはまた、最後のコマンドが入力を提供しないのに対し、最初のコマンドは出力を生成しないという事実にも依存します。

関連情報