bashがバックグラウンドジョブの一部であるときに$(date)を再評価する方法 - 可能な場合

bashがバックグラウンドジョブの一部であるときに$(date)を再評価する方法 - 可能な場合

オペレーティングシステムFreeBSD-12.2

私が使用する仮想プリンタ設定がありますsocat。このsocatコマンドはバックグラウンドで実行されます。入力ストリームを処理してそれを送信してgpcl6PDF文書を生成するシステムシェルを作成します。出力は特定のディレクトリのファイルに移動されます。ファイル名にはタイムスタンプを含める必要があります$(date -Iseconds)。問題は、このタイムスタンプは、コマンドのsocat開始後にのみ計算され、その後はカウントされないことです。私の質問は:データストリームが到着するたびに再評価する方法はありますか?

完全なコマンドは次のとおりです。

HPNP=4178 socat TCP4-LISTEN:4178,bind=192.168.216.179,fork,reuseaddr,su=hp3000 システム: "sed -r '1s/^.{42}//' | cat /var/spool/hp3000/forms /hll_inv_ljiiii_85.ovl - | gpcl6 -dNOSAFE -dNOPAUSE -sDEVICE=pdfwrite -sOutputFile=/var/spool/hp3000/np4178/HP3000-INV-"$(date -Iseconds)" - %0

一重引用符、二重引用符、引用符なしを試しました。コマンドは3つのオプションすべてで始まります。ただし、一重引用符と二重引用符は同じ結果を生成し、タイムスタンプはコマンドが開始された時刻に固定されます。引用符がないと、コマンドは開始されますが、コマンドに送信されたすべてのエントリーはパイプの破損エラーを継続的に発生させます。

2021/05/17 15:56:55 socat[17557] E write(5, 0x800b09000, 1460): Broken pipe
cat: stdout: Broken pipe
sed: stdout: Broken pipe

socat のマニュアルページには次のものがあります。

   SYSTEM:<shell-command>
          Forks a sub process that establishes communication with its
          parent process and invokes the specified program with system() .
          Please note that <shell-command> [string] must not contain ','
          or "!!", and that shell meta characters may have to be
          protected.  After successful program start, socat writes data to
          stdin of the process and reads from its stdout.
          Option groups: FD,SOCKET,EXEC,FORK,TERMIOS
          Useful options: path, fdin, fdout, chroot, su, su-d, nofork,
          pty, stderr, ctty, setsid, pipes, sigint, sigquit
          See also: EXEC

私が知る限り、シェルはフォークされますが、起動時に一度だけ発生します。これは、データストリームが到着するたびに$()構成が評価されない理由ですか?とにかく、これにも限界はありますか?

ベストアンサー1

引用符は$(date)コマンドに影響を与えないため、常にsocatコマンドを実行する直前に評価されます。

$(date)説明の目的で、コマンドを単純化するために引用符を使用しない方法を示す少し簡単なビューになることを願っています。

socat TCP4-LISTEN:flags SYSTEM:"sed | gpcl6 file-"$(date)"-suffix"
#                              ^in quotes        ^out    ^in     ^out

二重引用符の中に入れると、今のように評価されます(ただし、結果出力の空白は単語区切りではなく空白のままです)。一重引用符に入れると、オプションsocatを評価するために呼び出されたシェルはすべての呼び出しSYSTEMでオプションを評価します。

socat TCP4-LISTEN:flags SYSTEM:'sed | gpcl6 file-$(date)-suffix'

2つの異なるシステムで実行されているこのコマンドのペアを使用して、それらを実際に確認できます。

# Server
socat TCP4-LISTEN:4178,fork,reuseaddr SYSTEM:'cat >socat.$(date +%H%M%S).txt'

# Client
echo boo | nc remoteServer 4178

# Sever
ls șocat.*.txt

この変更を元のコードに再適用すると、次のような結果が得られます(便宜上、コマンドで使用される引用符の種類も変更しましたsed)。

HPNP=4178 socat TCP4-LISTEN:4178,bind=192.168.216.179,fork,reuseaddr,su=hp3000 SYSTEM:'sed -r "1s/^.{42}//" | cat /var/spool/hp3000/forms/hll_inv_ljiii_85.ovl - | gpcl6 -dNOSAFE -dNOPAUSE -sDEVICE=pdfwrite -sOutputFile=/var/spool/hp3000/np4178/HP3000-INV-$(date -Iseconds)-%03u.pdf -' &

おすすめ記事