バックグラウンドで実行されているプロセスによって端末が破損する可能性があります

バックグラウンドで実行されているプロセスによって端末が破損する可能性があります

私はこれを持っていますmakefile

all: 
        sudo watch "ls -l" > /dev/null &
        @echo line 1
        @echo line 2
        @echo line 3
        @echo line 4

ランニングwatchまたは何とか端末を変更する他のプロセス) 端子が破損しています。これが出力です。このように広いスペースを見ることができます。また、次の文章を書くと文字が見えません。

me@me:/tmp$ make
watch "ls -l" > /dev/null &
line 1
line 2
      line 3
            line 4
                  me@me:/tmp$ 

プロセスが端末を変更するのを防ぐ方法はありますか?
言うwatch1つだけ再現可能な例。デーモンとして実行する必要がある他のアプリケーションを使用していますが、それでも端末がハングします。


編集:このアプリケーションを実行します(この例ではアプリケーションはwatch)。sudo
解決策なしで始めることです。sudoこれにより端末は破壊されません。
これの欠点は、chownこのプロセスが必要ないことですroot:root

答え1

時計はデザイン的に端末を更新しました。オブジェクトを「監視」し、オブジェクトの現在のバージョン(または-dを使用してオブジェクトに対する変更)を表示します。ウォッチが役に立つ例は、CPU温度を監視したい場合に新しいターミナルを開き、次のコマンドを実行すると、出力がセンサーによって記録された温度で2秒ごとに更新されることです。

watch -x cat /sys/devices/pci0000:00/0000:00:18.3/hwmon/hwmon0/temp1_input

なぜ「ls -l」を見たいのか分かりません。出力を記録するシェルスクリプトを作成できますか?

#!/bin/bash

while :
do 
   date +"%H:%M:%S" >> /var/log/ls.log
   ls -l >> /var/log/ls.log   
   sleep 2
done

新しいファイルまたは変更されたファイルを記録するには、次の手順を実行します。

 #!/bin/bash
    
    while :
    do 
       find -newer /var/log/ls.log >> /var/log/ls.log
       date +"%H:%M:%S" >> /var/log/ls.log  
       sleep 2
    done

睡眠時間を増やしたいかもしれません。時計のデフォルト設定なので、私は2に設定しました。

出力がインデントされていて、出力後に入力した文字が表示されない理由は、Bashではなく端末によるものです。

ターミナルプログラムの設定を確認し、用語タイプがエンコードと一致していることを確認してください(例:utf8、ANSIIなど)。ターミナルはカーソルを行の先頭(\ r)にリセットするのではなく、カーソルを1行下(\ n)だけ移動します。これは、ファイルがWindowsで作成されてからLinuxに移動された場合、またはファイルがLinuxで作成されてWindowsに移動された場合にも発生する可能性があります。

入力した文字は、出力の最後の行の後に表示されます。だからあなたはそれを見ることができません。

答え2

プロセスが端末を変更するのを防ぐ方法はありますか?

まさか。端末の状態は端末全体に適用され、許可されているすべてのプロセスによって変更される可能性があります。

$ tty
/dev/ttys007
$ stty -a | grep ' erase'
        eol2 = <undef>; erase = ^?; intr = ^C; kill = ^U; lnext = ^V;
$ stty erase '#'
$ stty -a | grep ' erase'
        eol2 = <undef>; erase = #; intr = ^C; kill = ^U; lnext = ^V;

練習では、その変更をキャンセルする方法を理解できます。もう1つの練習は、どのシェルやプログラムがerase伝統的であるかをチェックすることです#(「UNIXプログラミング環境」(1984)に記載されています)。

そうしないと、インタラクティブプログラムがバックグラウンドで実行されるように設計されておらず、端末の状態を変更しなくても、その出力が他のプログラムの出力とインターリーブされて読みにくくなるか、SIGTTINまたは永続的な影響を受ける可能性があります。 SIGTTOU信号。バックグラウンドで端末と対話してみてください。ラダーリングは、端末の状態(またはラインプリンタ)がプロセスで予想される状態と同期しない一般的な問題です。 CR/NL処理に影響を与えるさまざまなフラグtermiosINLCRなどIGNCR)がマニュアルページに文書化されています。バックグラウンドプロセスでXを設定する必要がありますが、シェルがXをYに戻すとクラッシュが発生します。

一部のオペレーティングシステムには、プログラムが端末設定を変更するのを防ぐためのセキュリティフレームワークがあります。この場合、インタラクティブプログラムは設計どおりに実行されないか機能しなくなり、最終的に設定を正しく設定するためにセキュリティフレームワークを操作するのに多くの時間を費やす可能性があります。

tmux別のオプションは、別のウィンドウで実行されている他のプログラムを妨げない一意のpty(たとえば、下)でプロセスを実行することです。

stty -g(サポートされている場合)を使用すると、後で復元するために(一部の)端末設定を保存できますが、バックグラウンドプロセスが端末状態を永久に操作したり、バックグラウンドプロセスに復元された値と競合する設定が必要な場合は機能しません。ほとんどのプログラムは、起動時またはその他の特定のイベント(control+に応答しzてからフォアグラウンドに移動)でのみ端末の状態を変更します。プログラムを使用して、tcsetattr(3)次のことができます。端末状態の直接修正

一部のシェルは、プログラムが終了した後に端末の状態を復元するために他のシェルよりも優れています。 ZSHをHeirloom Bourne Shellなどと比較します。さまざまなプログラムは特定の端末設定を無視します。たとえば、ZSHはeraseの設定を無視し#ますが、他のプログラム(cat例:)では#古い文字を削除する必要があります。

練習のヒント:lnext「literally next」の略語は通常 control+vまたはstty -a何でもあります。プログラムはそれを尊重しないかもしれません...

答え3

  • watchデーモンの場合は、stdinをリダイレクト(addなど)して、< /dev/null最初に端末にアクセスしないようにすることもできます。
  • あなたはそれがデーモンだと言ったので、もう一つの方法は、システムまたは初期化で実行して、再びttyに触れないようにすることです。
  • これは単なるテストであり、復元が必要な場合でもあります。stty sane

関連情報