BLOGTIMES
» ArchiveList (Tag for "sh" )
«Prev || 1 · 2 · 3 · 4 · 5 · 6 · 7 · 8 · 9 · | Next»
2019/07/14

xargs を使ってコマンドを並列実行させる

sh  cli 

Linux 上のバッチで重い処理(例えば画像処理など)をする際に、複数プロセスを同時に起動したいということがあると思いますが、自分でマルチスレッドのプログラムを書くのは骨が折れます。そんなときに xargs を使うとかなり楽に複数プロセスの処理が書けることが分かったのでメモ。

以下の -P の部分がポイントで、これがプロセス数の指定になります。
時刻を見ると分かる通り、コマンドが 2 つずつ実行されていることが分かります。

$ seq 1 10 | xargs -P 2 -I {} bash -c "sleep 3 ; echo -n '{} ' ; date '+%Y/%m/%d %H:%M:%S'" 1 2019/07/14 15:03:26 2 2019/07/14 15:03:26 3 2019/07/14 15:03:29 4 2019/07/14 15:03:29 5 2019/07/14 15:03:32 6 2019/07/14 15:03:32 7 8 2019/07/14 15:03:35 2019/07/14 15:03:35 9 2019/07/14 15:03:38 10 2019/07/14 15:03:38

    at 15:18 |
    2019/04/30

    webdrivermanager で ChromeDriver を自動アップデート

    selenium  sh  java 

    久しぶりに selenium のスクリプトを起動しようとしたら、以下のような例外を吐いて起動しなくて困ってしまいました。

    File "/home/hoge/.pyenv/versions/3.7.2/lib/python3.7/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response raise exception_class(message, screen, stacktrace) selenium.common.exceptions.SessionNotCreatedException: Message: session not created: Chrome version must be between 70 and 73 (Driver info: chromedriver=73.0.3683.68 (47787ec04b6e38e22703e856e101e840b65afe72),platform=Linux 4.15.0-46-generic x86_64)

    エラーメッセージを読む限り、ChromeDriver と Chrome のバージョンが合っていないというエラーのようです。

    以前書いたとおり Chrome は apt を使って導入しているので、定期的にバージョンアップされます。
    ところが、ChromeDriver は手動インストールなので、これらのバージョンがズレてしまうというのが問題の根本的な原因です。

    エラーが出てから対処するというのでも良いのですが、やはりこういうのは未然に防ぎたいもの。
    というわけで、自動的に ChromeDriver を更新するための良い方法がないかと思って探してみたら、webdrivermanager というプロジェクトを見つけました。

    webdrivermanager はインストールされているブラウザのバージョンに合わせた Selenium 用のバイナリドライバを自動的にダウンロードしてくれるという java のプログラムです。Maven などに組み込んで動かすのが一般的なようですが、今回は単純にコマンドラインから起動して /usr/local/bin/chromedriver を更新するようなスクリプトを組んでみました。無駄な動きがないように、インストールされた Chrome のバージョンをファイルで覚えておいて、バージョンアップされている場合にのみ動作するようにしてあります。


      at 16:41 |
      2019/03/29

      コマンドが成功するまで繰り返し呼出すシェルスクリプト

      sh 

      成功するまでコマンドを繰り返し実行するシェルスクリプトを書いてみました。
      単純に永久ループさせてしまうと問題になる可能性もあるので、一定回数失敗したら諦めるようにしてあります。

      /path/to/command の部分を呼出したいコマンドに変更するだけです。
      最大リトライ回数(MAX_RETRY)やリトライ間隔(INTERVAL)については適当に調整してください。

      MAX_RETRY=5 INTERVAL=5 for i in $(seq 1 $MAX_RETRY); do echo "$i 回目" /path/to/command && break sleep $INTERVAL && /bin/false done if [ $? -eq 0 ]; then echo "成功!" else echo "ギブアップ!" fi

        at 18:39 |
        2019/03/18

        find で空ディレクトリを削除する

        sh 

        シェルスクリプトで空ディレクトリを探して削除する方法がないかと思って調べてみたら、思いのほか簡単でびっくり。
        以下のように find の -empty オプションを使えば1行で書けます

        例えば、30日以上古い空のディレクトリを削除する場合。

        find /path/to/some/dir -type d -empty -mtime +30 -exec rmdir {} \;

          at 19:23 |
          2019/01/18

          bat ファイルで YYYYMMDDHHMMSS を得るには

          bat  sh 

          バッチ処理を書いていると、ログやファイル名などに現在のタイムスタンプをつけておきたいことがあります。
          Linux のシェルスクリプトだと、以下のような感じで date コマンドを使えば簡単に YYYYMMDDHHMMSS の文字列を得ることができます。

          date '+%Y%m%d%H%M%S'

          ところが、Windows の bat ファイルの場合には一筋縄ではいきません。
          いろいろ調べてみて、同様の操作が一撃ではできないことが分かりました。
          とりあえず以下のように2行で書く感じにすれば YYYYMMDDHHMMSS が得られるようです。

          set ts=%time: =0% set ts=%date:~0,4%%date:~5,2%%date:~8,2%%ts:~0,2%%ts:~3,2%%ts:~6,2% echo %ts%

          参考


            at 19:32 |
            2018/12/29

            WSL の Ubuntu 上に簡易な CA を立ててみた

            wsl  ssl  sh  idrac 

            WSL 上の Ubuntu 上に OpenSSL を使って簡易な CA を立ててみたのでメモ。
            そもそもなんでこんな事をする羽目になったのかというと、iDRAC6 の仮想コンソールが開けないという問題*1にハマってしまったから。

            とりあえず以下のスクリプトを WSL のコマンドプロンプトに貼り貼り付ければ demoCA というディレクトリに CA が作成できます。
            必要があればBASE_SUBJ や CA_NAME は変更してください。

            genca.sh

            使い方はデスクトップに .csr ファイルを置いて、./sign.sh の引数に .csr ファイルの名前を渡せば、署名済みの証明書ができます。

            $ ./sign.sh host1.csr Using configuration from /usr/lib/ssl/openssl.cnf Check that the request matches the signature Signature ok Certificate Details: Serial Number: 0 (0x0) Validity Not Before: Dec 29 11:18:52 2018 GMT Not After : Dec 26 11:18:52 2028 GMT Subject: countryName = JP stateOrProvinceName = Tokyo organizationName = EXAMPLE commonName = host1.example.jp X509v3 extensions: X509v3 Basic Constraints: CA:FALSE Netscape Comment: OpenSSL Generated Certificate X509v3 Subject Key Identifier: 3B:2B:1A:91:74:43:B3:DB:D6:7E:0F:CD:F2:F6:91:D3:68:22:B9:2C X509v3 Authority Key Identifier: DirName:/C=JP/ST=Tokyo/O=EXAMPLE/CN=Example Certificate Authority serial:89:86:40:11:44:E8:21:6E Certificate is to be certified until Dec 26 11:18:52 2028 GMT (3650 days) Write out database with 1 new entries Data Base Updated

            stateOrProvinceName が CA と CSR で合っていないと以下のようなエラーが出るので、証明書を発行するときに CA 側で CommonName 以外の Subject は CA と同じものに上書きするようにしてあります。

            The stateOrProvinceName field needed to be the same in the CA certificate (###) and the request (###)

            at 21:48 |
            2018/11/03

            帰投機を見送ってから僕も帰投(入間基地航空祭 2018)

            jsdf  saitama  入間基地  航空祭  F-2  F-15  C-2  E-2  SH-60  UH-60  AH-1 
            F-2B(23-8111) - 帰投機を見送ってから僕も帰投(入間基地航空祭 2018)F-15(12-8803) - 帰投機を見送ってから僕も帰投(入間基地航空祭 2018)
            C-2(88-1207)タキシング - 帰投機を見送ってから僕も帰投(入間基地航空祭 2018)C-2(88-1207) - 帰投機を見送ってから僕も帰投(入間基地航空祭 2018)
            E-2C(34-3459) - 帰投機を見送ってから僕も帰投(入間基地航空祭 2018)SH-60K(21-8445) - 帰投機を見送ってから僕も帰投(入間基地航空祭 2018)
            AH-1S(JG-3449) - 帰投機を見送ってから僕も帰投(入間基地航空祭 2018)UH-60J(98-4588) - 帰投機を見送ってから僕も帰投(入間基地航空祭 2018)

            最後に帰投機の離陸を見届けて帰ります。

            松島の F-2B の隠し技

            松島の F-2B はどうやらブルーインパルスの演技中にエンジンを回していたようで、ブルーの演技後すぐに飛び立っていってしまいました。

            離陸時に羽根フリフリみたいなのもなかったので、ずいぶん淡泊だなぁ、もうちょっとサービスしてくれてもいいのになぁと思いましたが、TL を見てみるとタキシングの時にキャノピーの中から「自衛官募集」とか「#ブルーより蒼い方」という文字が書かれた紙を掲げるという渾身のネタをやっていたらしく、TL を見るとこれが大ウケだったみたいですね。

            C-2 には部隊マークなし?

            美保から来た C-2 にはなぜか部隊マークなし。
            ロービジで見えないだけかと思ったのですが、写真でも確認できないので、ついていないんですね。

            その他

            日本の E-2C が飛んでいるのを見たのは 2011 年以来でしょうか。陸自の AH-1S や海自 SH-60K、百里の UH-60J や U-125A、小牧の C-130H などもみんなに手を振られながら帰投していきました。


              at 14:26 |
              2018/07/21

              GeoLite2 用の CSV から GeoLite Legacy 用のデータベースファイルを生成する

              python  sh  programming 

              GeoIP-update がエラーを吐いているをずっと放置していましたが、エラーの原因を調べてみたところ、現行の Legacy Database は更新が停止されていました。現在はウェブから 2018 年 3 月版のみがダウンロードできる状態で、このファイルも 2019 年 1 月にはウェブサイトから削除されるというスケジュールになっているようです。

              GeoLite は後継版の GeoLite2 の提供が始まっているので、こちらに移行して欲しいようですが、今使っている全てのアプリが GeoLite2 に対応しているわけでもないというところが、頭の痛いところです。

              延命スクリプトを書いてみる

              ふと、GeoLite Legacy のデータベースは単純なので、無理やり GeoLite2 用の CSV から GeoLite Legacy の .dat を作ってみることはできないだろうかと思ってちょっと組んでみたら、1~2時間くらいで完成してしまいました。もしかしたら、同じように移行で悩んでいる人もいるかもしれないので、GitHub にスクリプトをアップしておきました。

              実際の .dat へのコンバートは mteodoro/mmutils に同梱されている csv2dat.py を使っています。GeoLite Legacy はどうやら国の種類が増やせないらしく、コソボ (XK) のデータの部分で以下のようなエラーを吐いてしまうので、この部分を回避するために少しパッチを当てたものを使っています。今後、国が増えたりするとパッチの部分を増やす必要がでてきますね。

              'XK': missing country. update pygeoip.const.COUNTRY_CODES?

              導入方法

              Python 2.7 にパスが通っていれば、こんな感じで導入や DB 生成ができるはずです。

              cd /opt git clone https://github.com/hsur/GeoLite2toGeoLiteLegacy.git ./setup.sh ./generate.sh

              標準で導入されている dat と生成された dat の比較は geoiplookup で行うことができます。

              $ geoiplookup -f /usr/share/GeoIP/GeoIP.dat 160.16.237.171 GeoIP Country Edition: JP, Japan $ geoiplookup -f GeoLiteCountry.dat 160.16.237.171 GeoIP Country Edition: JP, Japan

              最後に OS 標準の .dat のリンクを書き換えておけば導入は完了です。

              ln -sf /opt/GeoLite2toGeoLiteLegacy/GeoLiteCountry.dat /usr/share/GeoIP/GeoIP.dat

              データは1ヶ月に1回しか更新されないので、たまに手動で実行するくらいで大丈夫なはずです。


                at 21:44 |
                2018/04/21

                海自は装備試験機を展示 (2018 NAF Atsugi Spring Festival)

                kanagawa  厚木基地  jsdf  P-3  SH-60  C-130  P-1  prototype 
                UP-3C(51-9151) - 海自は装備試験機を展示 (2018 NAF Atsugi Spring Festival)USH-60K(51-8901) - 海自は装備試験機を展示 (2018 NAF Atsugi Spring Festival)
                USH-60K(51-8901) - 海自は装備試験機を展示 (2018 NAF Atsugi Spring Festival)P-1(3-5515) - 海自は装備試験機を展示 (2018 NAF Atsugi Spring Festival)
                C-130R(61-9051)内部 - 海自は装備試験機を展示 (2018 NAF Atsugi Spring Festival)C-130R(61-9051)コックピット入口 - 海自は装備試験機を展示 (2018 NAF Atsugi Spring Festival)

                  at 10:29 |
                  2018/04/13

                  log を常時監視して slack にポストする

                  sh  slack 

                  以前、「snmptrapd の通知を Slack に飛ばす」というのをやりましたが、ファイルを tail -f で監視しておいて、特定の文字(例えば [ERROR])が来たらそれを Slack で通知するというシェルスクリプトを組んでみました。

                  ベースがあるとあっという間にできますね。
                  いろいろオプションがついてしまっていますが、基本的にはバッファリングさせないようにするものです

                  #!/bin/bash SCRIPT_DIR=`dirname $0` cd $SCRIPT_DIR # ログとgrepの設定 LOGFILE="/path/to/log/file" GREP_RULE="[ERROR]" # Slack通知の設定 SLACK_WEBHOOKURL="(slackのWebHookURL)" SLACK_CHANNEL="(slackのチャネル)" SLACK_BOTNAME="(slackの投稿者名)" SLACK_FACEICON=":raising_hand:" tail -n0 -F "$LOGFILE" | grep --line-buffered "$GREP_RULE" | while read LINE ; do # slack notification WEBMESSAGE='```'`echo $LINE | sed 's/"/\\\\"/g' `'```' curl -s -S -X POST --data-urlencode "payload={\"channel\": \"${SLACK_CHANNEL}\", \"username\": \"${SLACK_BOTNAME}\", \"icon_emoji\": \"${SLACK_FACEICON}\", \"text\": \"${WEBMESSAGE}\" }" ${SLACK_WEBHOOKURL} >/dev/null done

                    at 17:34 |
                    «Prev || 1 · 2 · 3 · 4 · 5 · 6 · 7 · 8 · 9 · | Next»
                    » ArchiveList (Tag for "sh" )