スクリプトの実行中に標準入力(ユーザー入力)をキャプチャしてリダイレクトする

スクリプトの実行中に標準入力(ユーザー入力)をキャプチャしてリダイレクトする

次のように、スクリプト内のすべてのエントリに対してstdout / stderrをリダイレクトできます。

#!/bin/bash
exec > stdout_file
echo example

しかし、今ではスクリプト全体のstdinをファイルに書きたいと思います。私はこれを試しました:

#!/bin/bash
exec 0>stdin_file
sleep 5

sleepの実行中に「foo」と入力するとファイルに書き込まれませんが、bashはスクリプトの終了後に「foo」コマンドを実行しようとします。私は、これはbashがstdinをsleepのstdinにリンクしますが、sleepがstdinから読まないためだと思います。

私はすべてのユーザー入力がスクリプトコマンドの標準入力(ここでは「スリープ」と表示されている)に送信されるのではなく、ファイルにリダイレクトされることを望みます。

それ以外にも私も試してみました。

cat - >stdin_file &

しかし、bash は cats stdin をバックグラウンドで送信している間に接続を切断するので動作しません。

ベストアンサー1

あなたの目標は何であるかよくわかりませんが、端末に入って対話的にコマンドを発行するのは少し難しいかもしれません。そのために設計されたツールは次のとおりです。スクリプト(1)、util-linuxから。

以下を含むファイルがあるとしますbridge.sh

#!/bin/sh
read -p "What… is your name? " NAME
read -p "What… is your quest? " QUEST
read -p "What… is your favourite colour? " COLOUR
echo "Go on. Off you go."

次のコマンドを使用してターミナルセッションをキャプチャできます。

script -c ./bridge.sh bridge_script

ユーザーの入力にのみ興味があるので、次のものを使用できます。

script -c ./bridge.sh --log-in bridge_input_script

マニュアルページ警告:

スクリプトは、改行やバックスペースを含むすべてをログファイルに入れます。これは素朴なユーザーが期待するものではありません。

実際には、入力ログに各入力の末尾にデフォルトのCRがあることがわかります。 (言葉になります。クリックするとCRが記録されます。)

> cat -A bridge_input_script
Script started on 2023-05-24 09:46:19-04:00 [TERM="xterm-256color" TTY="/dev/pts/4" COLUMNS="124" LINES="40"]$
My name is Sir Lancelot of Camelot.^MTo seek the Holy Grail.^MBlue.^M$
Script done on 2023-05-24 09:46:32-04:00 [COMMAND_EXIT_CODE="0"]$

(これは、計測中のコマンドについてもっと知らなくてもできる最善の方法です。)

今後の分析に必要なすべてのデータを取得するために通常行うことは次のとおりです。

script -c ./bridge.sh --log-timing bridge_timing_log --log-io bridge_io_log

私は使うスクリプト再生(1)再生セッション:

scriptreplay --log-io bridge_io_log --log-timing bridge_timing_log -m 0.01

(私は時間にあまり気にしないので、-m 0.01最大遅延時間を10msに制限します。)

script以下を含むいくつかの追加のヒントがあります。スクリプトライブ(1)、どちら実際にセッションを再実行してください。ログから。 (足に銃を撃つこともできます。RTFM、注意してください!)

おすすめ記事