シェルスクリプトでは、シェルスクリプトと同じ標準入力を使用してバックグラウンドコマンドを開始しようとします。
#!/bin/sh
# ...
the-program &
ただし、the-program
上記の方法はシェルスクリプトと同じ標準入力にアクセスできません。私のシェルマニュアルによると(ダッシュ(1)):
シェルが対話型でない場合、非同期コマンドの標準入力はに設定されます
/dev/null
。
試してみましthe-program & <&0
たが、欲しい効果が得られなかったようです。標準入力はthe-program
まだです/dev/null
。
私はシェルスクリプトの標準入力をコピーし、何らかの方法で新しいファイルディスクリプタをバックグラウンドプロセスに渡して新しいファイルディスクリプタを生成することを検討しました。ただし、バックグラウンドプロセスは何らかの方法でこの新しいファイル記述子を標準入力/dev/null
にリダイレクトする必要があります。このアイデアが可能かどうかわからず、POSIX shで実装する方法もわかりません。
答え1
うん、POSIXsh
仕様要件非対話式シェルを介して非同期的に開始されたコマンドを呼び出すと(monitor
IOWジョブ制御オプションが有効になっていない場合)、その標準入力は/ dev / nullにリダイレクトされます。
ジョブ制御が無効になっている場合(参照
set
)-m
、非同期リストの標準入力は、明示的なリダイレクトが実行される前に同じ属性を持つファイルに割り当てられているかのように処理する必要があります/dev/null
。ジョブ制御が有効な場合、これは発生しません。すべての場合において、標準入力の明示的なリダイレクトはこのアクティビティを上書きする必要があります。
一般的な解決策は次のとおりです。
{ cmd <&3 3<&- & } 3<&0
これはあなたが考えているのと同じです。
例:
$ sh -c 'readlink /proc/self/fd/0 & wait' < /
/dev/null
$ sh -c '{ readlink /proc/self/fd/0 <&3 3<&- & } 3<&0; wait' < /
/
zsh
別のオプションは、シミュレーションでもこの要件を無視する方法を使用することです。sh
$ zsh -c 'readlink /proc/self/fd/0 & wait' < /
/
$ zsh --emulate sh -c 'readlink /proc/self/fd/0 & wait' < /
/