Bashスクリプトを改善する


8

問題なく問題なく実行されるように、Bashスクリプトを改善する必要があります。このスクリプトはそのds4drv中で使用しており、修正方法がわからない問題があります。

最初の問題は、コントローラーが検出されたときに常に実行または機能するとは限らないことです。そのためにudevルールを作成しましたが、検出されたときにこのスクリプトが常に実行されない理由が明確ではありません。

2番目の問題は、ds4drv通常のユーザーとして実行されるのではなく、rootとしてのみ実行できるようにすることです。

3番目の問題は、作成されたPIDロックファイルを処理する適切な方法がわからないため、PIDプロセスが存在しなくなったときに、PIDロックファイルが削除されるためです。実行中のインスタンスが1つだけになるように、bashスクリプトでPIDファイルを使用する方法に関する適切なドキュメントを見つけるのは困難です。

ここにds4drvのudevルールがあります: 50-ds4drv.rules

KERNEL=="uinput", GROUP="users", MODE="0666"
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="054c", ATTRS{idProduct}=="05c4", GROUP="users", MODE="0
666"
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", KERNELS=="0005:054C:05C4.*", GROUP="users" MODE="0666"
ACTION=="add", SUBSYSTEM="usb", ATTRS{idProduct}=="054c", RUN+="/home/user/scripts/ds4check.sh", GROUP="users"
, MODE="0666"

それはudevルールがそうあるべきであると私はかなり確信しています、それはGROUPユーザーのための読み書きなので、パーミッションは私にとって正しいようです。bashスクリプトが実行され、コントローラーデバイスが接続されたときにこのルールが自動的に実行されるように設定されると、コントローラーデバイスが接続されていない場合など、一部のゲームが応答しなくなるという問題のいくつかのインスタンスがあるようです作用することが/dev/js0なく、その代わりに作用する/dev/js1代わりに。特にrootとして実行されていない場合、このエラーを返すことがよくあります。

OSError: [Errno 13] Permission denied: '/dev/input/event17'

そしてもちろんbashスクリプト。 ds4check.sh

#!/bin/bash
# DS4 Check Script

pidfile=/tmp/ds4drv.pid

# check if process is already running
for pid in $(pidof -x /home/user/scripts/ds4check.sh $pidfile); do
    if [ $pid != $$ ]; then
      echo "[$(date)] : ds4check.sh : Proccess is already running with PID $pid" >> /home/user/.cache/ds4drv.log
      exit 1
# if not running then run and apply config
      else  ( ds4drv --hidraw --config /home/user/.config/ds4drv.conf )

      exit 0
    fi
done

# remove PID file on exit... hopefully
trap "srm -rv -- '$pidfile'" EXIT >> /home/user/.cache/ds4drv.log

udevルールを投稿できますか?
Joe

@ジョーあなたが私の投稿を読んだことがあるなら、あなたはそれが私のメインの投稿にすでにあるのを見るでしょう。

の使用/tmpは、ローカルのセキュリティ上の欠陥(スクリプトを実行しているユーザーに対する任意のファイル削除)であり、使用するのが適切/var/runです。それ以外の場合、PIDファイルは、物事がどのようにバラバラになるかに応じて、エッジケースと落とし穴を備えたまあまあのソリューションになります。
2016

回答:


1

2点気になる

  • よく知らないPIDファイルですがpgrep、回避策として使用することをお勧めします。
  • ds4drvデーモンのようですが、udev実行時間の短いプロセスのみをサポートします。

    RUN {タイプ}

    ...

    これは、非常に短時間のフォアグラウンドタスクにのみ使用できます。イベントプロセスを長期間実行すると、このデバイスまたは依存デバイスの以降のすべてのイベントがブロックされる可能性があります。

    デーモンまたは他の長時間実行プロセスを開始することはudevには適切ではありません。切り離されているかどうかに関係なく、フォークされたプロセスは、イベント処理の終了後に無条件に強制終了されます。

そのスクリプトのコピーを作成します。

#!/bin/bash
# DS4 Check Script

pgrep ds4drv || ds4drv --hidraw --config /home/user/.config/ds4drv.conf & disown

1
はい、ds4drvバックグラウンドで実行されるデーモンですが、現在のスクリプトに問題があるため、接続できず/dev/js0、代わりに新しいインスタンスに接続しています/dev/js1。私のudevルールはそれを実行するように修正する必要があり/dev/js0ますが、正しく実行されていません。小さなスニペットに関しては、おそらくその二重パイプのために、意図したとおりに機能しません。実行しようとすると、実行されないためです事。

@ user94959、それを修正することはできませんjs0、カーネルは各デバイス接続(同じデバイスが再接続されている場合でも)ごとに増分を行います。シンボリックリンクを作成するには、udevルールを/ addするのが最善です。上流のドキュメントを確認しました。起動時にデーモンを起動するサービスファイルを使用することをお勧めします。その方法を使用することの不便さを尋ねてもらえますか?
user.dz

問題は/dev/js0デフォルトのユーザーレベルにあると思いますが、スクリプトはルートレベルで実行するように強制しているため、/dev/js1代わりにスクリプトをアタッチします。必要なのは、スクリプトをルートではなく通常のユーザーとして実行することです。rootとしての実行を強制する理由は、他の方法では適用していない構成ファイルがあるためです。デーモンは、通常のユーザーではなくrootを想定しています。通常のユーザーレベルで実行するためにできることは少しあったと思いますが、私にはうまくいきませんでした。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.