この質問は無意味ですが、始めましょう!私はbashでIRCクライアントを開発していますが、いくつかのコードを見つけて、私が開発しているIRC bashボットコードに追加し始めました。単純化するために分解してみました。 GNU bash、バージョン4.3.48(1) - リリース
#!/bin/bash
#!/user/bin/perl
function status_line() {
echo -en '\e7' "\e[${status_line_row};0f" '\e[2K'
echo -en "\e[4;44mSTATUS: $nick in $channel @ $channel\e[0m"
echo -en '\e8'
}
function read_line() {
while true
do
while read -r -t1
do
status_line
echo -en '\e[2K\r> '
echo "PRIVMSG $channel :$REPLY" >> $input
done
done
}
. bot.properties
input=".bot.cfg"
echo "Starting session: $(date "+[%y:%m:%d %T]")">$log
echo "NICK $nick" > $input
echo "USER $user" >> $input
echo "JOIN $channel" >> $input
read_line | tail -f $input | openssl s_client -connect $server:6697
このコマンドを実行し、端末に入力を入力した後、正しく入力して$ REPLYをIRCに送信しますが、read_line内でstatus_lineとecho -en '\ e [2K \ r> 'を正しく実行できません。入力を読み取る理由は混乱していますが、入力前の2行は機能しません。 IRCにメッセージを送信した後、これを確認するためにbash -xを実行しましたが(以下)、-xなしでは問題は解決されませんでした。
+ status_line
+ echo -en '\e7' '\e[;0f' '\e[2K'
+ echo -en '\e[4;44mSTATUS: Omen in #lair @ #lair\e[0m'
+ echo -en '\e8'
+ echo -en '\e[2K\r> '
+ read -r -t1
+ true
完全なコードを見るにはここをクリック>https://pastebin.com/cHLiwZNf
ベストアンサー1
function read_line() {
...
while read -r -t1; do
status_line
echo -en '\e[2K\r> '
echo "PRIVMSG $channel :$REPLY" >> $input
...
}
read_line | tail ...
read_line で status_line と echo -en '\e[2K\r> ' が正しく実行されません。入力を読み取る理由は混乱していますが、入力前の2行は機能しません。
内部的にをread_line
使用して標準入力から読み取った後、を使用してread
標準出力に印刷できますecho
。 ($input
他でも動作しますecho
が問題ありません。)
read_line
パイプラインの一部として関数を呼び出す方法を確認し、read_line
stdinとstdoutがどのようにリンクされているかを考えてみましょう。パイプは、関連するコマンドの入出力ストリームに対して何をしますか?tail
標準入力にどのような役割を果たしますか?
また、これが>
ユーザーにプロンプトでなければならない場合は、おそらく印刷する必要があることに注意してください。今後それ以降ではなく電話してくださいread
。これを実行するか、while echo -en '\e[2K\r> '; read -r -t1; do ...
それを使用してread -p
プロンプトを印刷してください。端末が通常の方法で設定されている場合、ユーザーがEnterキーを押すと何かがread
印刷されると画面がスクロールします。ステータスバーが画面上部にあると、スクロールして見えなくなります。これに対して何かをする必要があり、既存のncurses
UIライブラリを使用する方がはるかに簡単です(たとえば、シェルで端末処理を手動で変更するなど)。
IRCクライアントのもう一つの問題は必要同時に2つの場所で読むことができます:ユーザーの入力とネットワークのデータ。処理のために出力をopenssl
スクリプトに戻すのはそれ自体が少しぎこちなく、同時に両方を読む必要がある方が悪いです。
実際の解決策は、以下を使用することです。システムselect()
コール(またはpoll()
)。 Bashは/dev/tcp
疑似ファイルを介してネットワークソケットへのアクセスを提供しますがselect()
。
したがって、実際に使用する2つの重要な理由があります。実際のプログラミング言語そして殻ではないこのために。
もちろん、ちょっとクレイジーな練習でこれを行う場合は大丈夫ですが、そうであれば、この問題を解決する前にシェル言語に少し慣れておくことをお勧めします。また、実際の影響を受けずに限られた環境でプログラミングをしたい場合は、次のいずれかをお勧めします。ジャック電子工事そのような理由で。