アンドロイドアプリ開発時に自作したお気に入りシェルスクリプト


先日アンドロイドアプリをリリースしました。

エンジニア・デザイナが何か一緒に作ったり、勉強会開いたりを気軽に出来るコミュニティツールです。

EDICPAT

アプリを作る時に自作して、いい感じに動いていたツールというか、シェルスクリプトを公開します。なお、前提としてPCはLINUX(Manjaro)を使用していますが、Shell(とかadbとか)が動けば他のOSでも使えるはずです。

クライアント編 (adb)

  • apkを端末にインストールする用のShell (install.sh)
#! /bin/bash

if [ $# == 0 ]; then
  adb install -t -r app-debug.apk
  exit 0
fi

if [ $1 = "-p" ]; then
  adb -s [自分のデバイス1] install -t -r app-debug.apk 
elif [ $1 = "-t" ]; then
  adb -s [自分のデバイス2]  install -t -r app-debug.apk
elif [ $1 = "-e" ]; then
  adb -e install -t -r app-debug.apk 
else 
  echo "invalid option $1"
  echo "usage $0 [-p|-t|-e]"
  echo "no option: any conected device"
  echo "-p: pixel3"
  echo "-t: tablet"
  echo "-e: emulator"
fi

PCに接続されている端末(エミュレータ含む)が一つなら、カレントディレクトリにapp-debug.apkかそのシンボリックリンクを置いて、./install.shだけでインストール出来ます。PCに2つ以上の端末が刺さっている場合、./install.sh -pとか、-tとかで使い分けます。-pと-tは自分が持っている端末がたまたまピクセルとタブレットだったのでそうしていますが、そこは自分の環境に合わせて適当に変えるイメージです(galaxyなら-pを-gにしてデバイス名もgalaxyのにするとか)。-eはエミュレータの端末です。

デバイス名となっている所は、adb devicesを実行すると見える端末のデバイス名を入れます。

  • apkを端末からアンインストールする用のシェル(uninstall.sh)
#! /bin/bash

if [ $# == 0 ]; then
  adb uninstall com.engineer_forum.engineer_forum
  exit 0
fi

if [ $1 = "-p" ]; then
  adb -s [自分のデバイス1] uninstall [アプリパッケージ名]
elif [ $1 = "-t" ]; then
  adb -s [自分のデバイス2]  uninstall [アプリパッケージ名]
elif [ $1 = "-e" ]; then
  adb -e uninstall [アプリパッケージ名]
else 
  echo "invalid option $1"
  echo "usage $0 [-p|-t|-e]"
  echo "no option: any conected device"
  echo "-p: pixel3"
  echo "-t: tablet"
  echo "-e: emulator"
fi

使い方はインストール用とほぼ同じです。./uninstall.shとか、./uninstall.sh -pとかって使います。

ちなみに再インストール(一度削除してもう一度インストール)は、install.shとuninstall.shを組み合わせれば簡単に出来るので割愛します(再インストールシェルはめっちゃ使った)。あと、組み合わせれば繋がってる全ての端末でインストール・アンインストールみたいなことも出来ます。

  • 端末のDBのファイルをPCにコピーする (pulldb.sh)
#! /bin/bash
if [ $# -eq 0 ];then
        echo "Usage ${0} [-p|-t|-e]"
        exit 1
fi

if [ $1 = "-p" ];then
        adb -s [自分のデバイス1] exec-out run-as [アプリパッケージ名] cat databases/[ローカルDB名] > "[ローカルDB名_1]" 
elif [ $1 = "-t" ];then
        adb -s [自分のデバイス2] exec-out run-as [アプリパッケージ名] cat databases/[ローカルDB名] > "[ローカルDB名_2]"
elif [ $1 = "-e" ];then
        adb -e exec-out run-as [アプリパッケージ名] cat databases/[ローカルDB名] > "[ローカルDB名_3]"
else
        echo "Usage ${0} [-p|-t|-e]"
        exit 1
fi

これもinstall.shと使い方は同じ、ピクセルからDB取得したいときは./pulldb.sh -pとかって使います。一応保存する時のファイル名は変えておいた方が便利と思い変えてます。

  • PCで加工等したDBファイルを端末側にコピーする (pushdb.sh)
#!/bin/bash
if [ $# != 1 ]; then
    echo "usage: $0 db_filename" 1>&2
    exit 0
fi

PKGNAME="[アプリのパッケージ名]"
DBFILENAME=$1

adb push ${DBFILENAME} /sdcard/
adb shell "run-as ${PKGNAME} cp /sdcard/${DBFILENAME} /data/data/${PKGNAME}/databases/[ローカルのDBファイル名]"

./pushdb.sh [DBファイル名]
として使います。あんまり使わないので-s対応しませんでしたが、install.sh等と同様に、シェルスクリプト中で-s [デバイス名]を追加すれば複数端末接続時に端末指定が出来ると思います。

サーバ編 (curl)

  • 任意のJSONをサーバにcurlで送りつけるシェル (send.sh)。JSONファイルは外出し
#! /bin/bash

errmsg="Usage: $0 [-l|-s] command"

if [ $# -ne 2 ]; then
        echo ${errmsg}
        exit 1
fi

host=""
if [ $1 = '-l' ]; then
        host='localhost:[ローカルサーバのポート番号]'
elif [ $1 = '-s' ]; then
        host='[リモートサーバのURL]'
else
        echo ${errmsg}
        exit 1
fi 

command=$2

curl -X POST ${host}/${command}.js -H "Accept:application/json" -H "Content-type: application/json" -d @${command}.json

./send.sh [-l|-s] [Command名]として使います。JSONファイルにはCommand名.jsonと付けます。引数の-lは、ローカルPC上に立ち上げたダミーサーバにJSONを送りつけたい時に使います。-sはリモートサーバに送りつけたい時に使います。コマンド中の -d @~~~はファイル内容のデータを送信してくれるオプションです。
JSONファイルは例えばこんなのです。
member.json

{
        "ProductId":12345,
        "Color":"Black",
        "Category":[1,2,5],
}

./send.sh -s member.jsonとすれば、製品ID 12345、黒色、カテゴリー 1,2,5に属する製品、というデータがリモートサーバに飛ばせます。

上のコマンドを応用し、末尾に&を付けてバックグラウンド実行するのを1000回とか10000回とかループさせて、サーバが過負荷に耐えられるかの試験が出来たりします(リモートサーバーに対してやると怒られるのでローカルにダミーサーバを立ててテスト目的でやります)。

LINUXで開発効率化楽しい

こういう便利シェルみたいなのを作り出したりすると、開発そっちのけでシェル作る作業の方が楽しくなってしまって、費やす時間と効果のバランスがどうなんだって感じになってきちゃったりします、、、が、あまり気にしないことにしています。中には一回しかやらない作業なのにわざわざシェルとかawkとかでプログラム組んでスマートに解決しようとしたりしてしまいますが、最終的には全然スマートじゃないという...

しかし狙い通りに効率化が出来ると、一人でニヤニヤしてしまう性癖があります。こういうちょっとしたLINUXの「思い通りに動く感」って本当に好きです。