Bash機能が行を正しく実行したくないようです。

Bash機能が行を正しく実行したくないようです。

この質問は無意味ですが、始めましょう!私は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_linestdinとstdoutがどのようにリンクされているかを考えてみましょう。パイプは、関連するコマンドの入出力ストリームに対して何をしますか?tail標準入力にどのような役割を果たしますか?


また、これが>ユーザーにプロンプ​​トでなければならない場合は、おそらく印刷する必要があることに注意してください。今後それ以降ではなく電話してくださいread。これを実行するか、while echo -en '\e[2K\r> '; read -r -t1; do ...それを使用してread -pプロンプトを印刷してください。端末が通常の方法で設定されている場合、ユーザーがEnterキーを押すと何かがread印刷されると画面がスクロールします。ステータスバーが画面上部にあると、スクロールして見えなくなります。これに対して何かをする必要があり、既存のncursesUIライブラリを使用する方がはるかに簡単です(たとえば、シェルで端末処理を手動で変更するなど)。

IRCクライアントのもう一つの問題は必要同時に2つの場所で読むことができます:ユーザーの入力とネットワークのデータ。処理のために出力をopensslスクリプトに戻すのはそれ自体が少しぎこちなく、同時に両方を読む必要がある方が悪いです。

実際の解決策は、以下を使用することです。システムselect()コール(またはpoll())。 Bashは/dev/tcp疑似ファイルを介してネットワークソケットへのアクセスを提供しますがselect()

したがって、実際に使用する2つの重要な理由があります。実際のプログラミング言語そして殻ではないこのために。

もちろん、ちょっとクレイジーな練習でこれを行う場合は大丈夫ですが、そうであれば、この問題を解決する前にシェル言語に少し慣れておくことをお勧めします。また、実際の影響を受けずに限られた環境でプログラミングをしたい場合は、次のいずれかをお勧めします。ジャック電子工事そのような理由で。

おすすめ記事