2025-01-27

iOS の iSH を使いショートカットでシェルスクリプトを実行させる具体的方法

 

【2025-02-01 追記・他の方法】

ショートカットのアクション「SSH経由でスクリプトを実行」を iPhone 内で実行するやり方で、記事末に記載

 

こちらの方が簡単にできて本命かも!!

 

 

iOS の iSH(Alpine Linux)でシェルスクリプトを自動実行させたい

 

この記事で、シェルスクリプトをショートカットを使って自動実行させる方法についての考え方を記載しました。

 

iSH は Android の Termux 相当のターミナルエミュレーターで、Alpine Linux ベースです。

パッケージを自由に追加できますのでいろいろなことが可能になります。

 

iPhone 向けのターミナルエミュレーターには a-Shell もありますが、こちらは機能が限定的なので、iSH の方が使い勝手が格段によい。

 

 

その iSH で作成したシェルスクリプトをショートカットで実行できると、ショートカットでできることの幅が拡がります。

 

 

 

 

本記事では具体的なやり方を事例を踏まえて記載します。

 

 

1.ショートカットのオートメーションの設定をします

 

ショートカットは、次の事例にします

 

   ・iPhone を電源に接続したとき

   ・アクションでクリップボードに「on」を設定

      アクションはショートカットと iSH に共通に操作可能なものを使います

      本事例ではクリップボードを使っていますが、特定ファイルの有無や、特定ファイルの内容
      なども共通操作可能です

 

クリップボードの内容を、あとに記述の crontab に設定した iSH のシェルスクリプトで判定し「on」ならば目的のシェルスクリプトを実行させます

 

そこで「ショートカット」⇨「オートメーション」右上の + をタップして新しいオートメーションを開始します

 

「充電器」を選び「接続されている」をチェック、「すぐに実行」をチェックし右上の「次へ」をタップ

 

「新規の空のオートメーション」をタップ

 

「アクションを検索」欄に「テキスト」を入力し、現れた「テキスト」アクションをタップ

 

テキスト欄に「on」を入力します


続いて「アクションを検索」欄に「クリップ」と入力します

 

「クリップボードにコピー」アクションを選び、詳細の「有効期限」を「空白」設定します

 

 

つまり、クリップボードに「on」を設定するアクションです

 

同様に「充電器」が「接続解除されている」オートメーションを作成し、こちらの方は「テキスト」に「off」を入力します

 

「電源から接続解除」と「電源に接続」が追加設定したオートメーション
 

 

ショートカット側の設定は以上で終わりです。

 

 

 

2.iSH アプリの設定を変更

 

「設定」⇨「アプリ」⇨「ほかのアプリからペースト」を「許可」に変更します

 

これは iSH がクリップボード参照時に「参照を許可するかどうか」の問い合わせをさせないための設定です

 

 

 

3.ファイルアプリでシェルスクリプトを作成

 

ファイルアプリを開き右下の「ブラウズ」をタップします

 

「場所」⇨「iSH」とし「/usr」をタップ

 

chk.sh という名前のシェルスクリプトを作成します

 

これは「判定要素(本事例ではクリップボードの「on」「off」)を確認」するシェルスクリプトで crontab から呼び出されます

 

次のような内容です

 

res=$(cat /dev/clipboard) #クリップボードの内容を得る
if [ $res = "on" ]; then #クリップボードの内容が "on" なら
   sh /usr/swstat.sh # swstat.sh を実行
   echo "off" > /dev/clipboard #クリップボードに "off" を設定
fi

 

クリップボードが「on」ならば目的のシェルスクリプト swstat.sh を実行し、クリップボードを「off」設定します

 

 

目的のシェルスクリプト swstat.sh を作成します

 

内容は次のようなスクリプトです

 



 

SwitchBot plus の状態を得て、結果を /usr 配下の stat というファイルに書き込むスクリプト事例ですが、かなりいろいろな処理を含んでいます

 

本事例は uuidgen / openssl / curl を追加パッケージとしてインストールし、トークン・Unix time・nonce を合成した認証情報を生成して base64 でエンコードして curl を叩いています

 

Unix time をミリ秒で得るため coreutils もインストールして date コマンドでミリ秒にしています


結果は stat というファイルに書き込みしています


また UTC 年月日時刻を JST 年月日時刻に変換して、stat ファイルに追記しています

 

 

このシェルスクリプト事例は SwithBot plus の状態を得ていますが、もちろん SwitchBot plug のオン・オフ制御も可能です。

 

なので、それを使って例えば 80% 充電したら SwitchBot plug をオフにする、といった自動化も可能になります。

 

 

スクリプトは実際に実行させたいものを作成すればよい

 

 

 

 

4.iSH での作業

 

iSH を起動します

 

crontab -e として編集開始し、次の設定をします


* * * * * for i in `seq 0 10 59`; do (sleep ${i}; sh /usr/chk.sh ) & done;


10秒ごとに chk.sh をバックグラウンドで起動する crontab です


iSH のプロンプトで次のコマンドを入力して2つのシェルに実行権を与え、crond で cron デーモンを起動します

 

また、iSH をバックグラウンドで動作させます

 

$ cd /usr # /usr にディレクトリを移動する
$ chmod 700 chk.sh swstat.sh # chk.sh と swstat.sh に実行権を与える
$ crond # cron デーモンを起動
$ cat /dev/location > /dev/null & # iSH バックグラウンド化のおまじない

 



5.オートメーションのアクションをテスト

/usr 配下の stat ファイルに swstat.sh 実行結果が書き込まれるかをアクションテストで確認する


ショートカットのアクションの右下にある をタップしてアクションをテストします

 

「電源に接続」のアクション内容



このアクションではクリップボードに「on」を書き込んでいます

 

「on」になると crontab で設定した chk.sh での判定が真になり、swstat.sh が実行されます

 

その結果 /usr 配下の stat ファイルには次のような内容が書き込まれます

 


 

 

実際に iPhone を電源に接続すると目的のシェルスクリプトが実行されます。

 

また電源から切断するとクリップボードにはショートカットによって「off」が設定されて chk.sh は何もしない判定になります。

 

 

 

以上が任意のシェルスクリプトをショートカットから実行させる具体事例です。

 

本事例では 10秒間隔で「判定要素を確認」なので、実際にシェルスクリプトが実行されるまでに最大 10秒のタイムラグが発生しますが、実際的に問題はないでしょう。

 

 

「ショートカットでシェルスクリプトを実行できる」ことが重要ですから。

 

 

 

 

 

【2025-02-01 追記・他の方法】

ショートカットのアクション「SSH経由でスクリプトを実行」を iPhone 内で実行するやり方

 

iSH で sshd を動作させ、ショートカットでこの sshd に ssh で接続してシェルやコマンド(群)を実行させるやり方です。

 

参考: https://github.com/januszoles/ish

このサイトの[📎SSH from the same device (not tested yet)]に「未テストだが同じデバイスから ssh する」とあり、下記の記述があります。

 

if you are trying to connect via ssh from the same device, make sure you set the port configuration of sshd to use a non standard one (greater than 1024, eg: 22000) .  You can do this by editing  /etc/ssh/sshd_config  and set Port 22000 (Replace 22000 with any non-standard port).  After this, you can ssh (from iSH itself) using  ssh root@localhost -p 22000

 

このサイトに書かれているとおりに設定してみました。

 



iSH を開きます。

 

$ apk add openssh # openssh をインストール
$ passwd # 接続用パスワードの設定


[ファイル]⇨[etc ディレクトリ]⇨[ssh ディレクトリ]⇨[sshd_config を開く(エディターが開く)]


・13行目の「# Port 22000」のコメントを外す

・最終行の「PermitRootLogin yes」を確認「no」となっていた場合「yes」に変更

・保存して編集を終了

 

 

$ cat /dev/location > /dev/null & # iSH をバックグラウンド動作

$ /usr/sbin/sshd # sshd を起動(ssh サーバーとして起動)

 

 

ショートカットを開き、アクション「SSH経由でスクリプトを実行」を選択し、下図のように設定します。

 


 

スクリプト欄には実行させたいシェルスクリプトやコマンド(群)を記述し、ショートカット名を「シェル実行」とでもします。

 

 

ホストは iPhone 自身を示す localhost(127.0.0.1)を指定します。

 

ポートは 22000 を指定します。

 

ユーザは root を指定します。

 

認証は「パスワード」を選択し、その下のパスワード欄に passwd コマンドで設定したパスワードを設定します。

 

公開鍵認証方式にすることもできます。

その場合はパスワード設定(入力)は不要です。

 

 

 

右上の完了をタップして設定は終わりです。

 

 

本事例のシェルスクリプトは swstat.sh というシェルファイル名で内容は次図です。

 


 

ショートカットを開きます。

 


 

左上の「シェル実行」が作成したショートカットです。

 

これをタップすると ssh で iPhone 自身に接続して swstat.sh を実行します。

 

結果は stat というファイルに書き込まれます(下図)。

 

 


 

 

 

 

 

 

 

2025-01-24

iOS の iSH(Alpine Linux)でシェルスクリプトを自動実行させたい

 

iOS のショートカットはシェルスクリプトを iPhone で実行するようなアクションを起こすことができません。

 

「SSH 経由でスクリプトを実行」というのはリモートコンピューターでスクリプトを実行するもので、結果は stdout で得られますが、スクリプトを iOS 内で実行はできません。

 

 

iSH をインストールすれば Alpine Linux エミュレーターを iPhone で使うことができ、任意のシェルスクリプトを作成して iSH 内で実行できます。

 

しかし、このときのシェルスクリプトを iPhone のショートカットから実行させることができないのです。

 

iPhone のショートカットには iPhone 内でショルスクリプトを実行させる仕組みがないのです。

 

iSH の開始時に自動でシェルスクリプトを実行させることは可能なのですが、2度目以降の開始時には自動実行されません。

 

これはアプリが終了していないからで、ホームボタンを二度タップ後に現れるアプリリストをスワイプして初めて次の開始時に自動実行されます。

 

Android の Termux は起動時シェルスクリプト自動実行が可能で、exit 後に再度開けばこれが機能します。

 

iPhone はこのような動作にはならないので、起動時シェルを設定しても意味がありません。

 

 

なお iPhone にはワンタップでアプリを終了させる機能がありません。

 

そのためかショートカットにアプリを終了させるアクションがない、ということでしょう。

 

 

このような、iPhone とそのショートカットの制約(不完全さ、といっても過言ではないでしょう)ゆえにまともな自動化ができません

 

 

 

Android には Tasker、Macrodroid、Automate などの優れた自動化アプリがありますが、iOS には同等のアプリがありません。

 

また Termux: Tasker プラグインをインストールすれば Tasker や Macrodroid で任意のシェルスクリプトを実行することができますが、iPhone はこういうことができません。

 

 

アップルのポリシーという闇のせいで Android では可能な自動化が同等にはできず、やると違反アプリとして削除されてしまうでしょう。

 

実は iSH も一度削除の憂き目に会っています。

 

 

iOS 上の iSH は自分で終了するコマンドが空振りします。

 

   ・exit コマンドは再起動されてしまい、終了しないのです

   ・poweroff コマンドは空振りします

 

ベースとなっている Alpine Linux 自体は exitpoweroff で終了します。

 

これは iOS のせいなのか、iOS 上の iSH の仕様なのかはわかりません。


推定ですが、アップルのポリシーに抵触しないように、iSH 側で「終了」させないようにしているのではないか、と。

 

なんとも半端な欠陥品ともいえるショートカットであり、iPhone 自体の制約でできないことがもどかしい状態です。

 

以上のようなこともあって、わたしは iPhone よりも Android の方が好みです。

 

 

 

 

いずれにせよ、ない知恵を絞り、どうすればシェルスクリプト自動実行を、ショートカットと iSH で代替できるか、を考えてみました。

 

 

1.「ある判定」をするシェルスクリプトを組み、cron を使って例えば 10秒ごととか、30秒ごととか、1分ごととかにこのスクリプトを動作させます。

 

「ある判定」要素はショートカットで設定しますが、ショートカットと iSH シェルスクリプトに共通的に操作可能な要素にします。

 

例えば、

 

   ・特定のファイルが特定のフォルダに存在するか否か

      特定ファイル名の変更で「存在」、「非存在」を判定

   ・特定のファイルの「内容」で判定

   ・クリップボードの「内容」で判定

    など

 

です。

 



2.ショートカットで設定された「ある判定」要素が、スクリプトでの判定条件に一致の場合に、「ある判定」を行うスクリプトが「別のスクリプト」を実行するのです。

 

「別のスクリプト」がショートカットで実行させたい目的のスクリプトです。

こうすることによってショートカットで設定した判定要素に従って目的のスクリプトを実行させることが可能になります。

 

判定時間間隔は、通常の crontab 設定では最小が1分ですが、crontab 設定を工夫すれば1秒以上の任意の時間間隔で判定するようにできます。

 

 

 

3.以上を実現するために、iSH で cron を使います。

 

iSH は Alpine Linux のエミュレーターで、crontabcrond は標準で入っています。

 

iSH はまた、パッケージを追加できますのでコマンドラインでいろいろなことが可能になります。


crontab には次の設定をします。

 

   * * * * * for i in `seq 0 10 59`; do (sleep ${i}; コマンド) & done;

 

例は 10秒間隔でコマンドを実行します。

 

コマンド部分は「ある判定」をするシェルスクリプトを設定します。

 

「ある判定」をするシェルスクリプトはバックグラウンドで動作させますが( 設定)、これはコマンドの実行にかかる時間が次のコマンド実行開始時間のズレになるのを防止のためです。

 

判定が一致の場合に「別のスクリプト」を実行するようにし、cron がループ処理に陥らないように「判定条件を不一致」に変更します。

 

crond の停止は kill $(pidof crond) とするとできます。

 

これによりシェルスクリプト内で crond を停止処理することができます。

 

こうすることで任意の時間間隔で「ある判定」が可能になります。 

 

時間間隔を大きくすれば、スクリプト実行までのタイムラグが生じますし、小さくすればタイムラグが少なくて済みますが、あまり小さくするとバッテリー消費が多くなります。

 

10 〜 30秒程度かな?   と。

ーーーーーーーーーーーーーーー

 

 

 

 

iSH を、iPhone のロック中でも動作させ続けるためバックグラウンド化します。

 

これは次のおまじないをします。

 

   cat /dev/location > /dev/null &

 

そして crond をコマンド入力して cron のデーモンを起動します。

 

ps a で "cat /dev/location" と "crond" タスクの起動状態を確認します。

 

 

実は cat /dev/location はバックグラウンド動作のため結構バッテリーを消費します。

 

これに比べれば crond でのバッテリー消費は大したものではありません。

 

 

 

以上のような、ショートカットと iSH 連携によって、ショートカットのアクションにより、目的のシェルスクリプトが実行できる具体的なやり方は本ブログに記載予定です。

 

 

 

 

 

 

 

 

2025-01-12

iPhone で unix time をミリ秒で得る 〜 Termux 代替の iSH を使う【2025-01-14 書き直し】

 

 

Android の Termux 相当を iPhone で実現するには iSH や a-shell アプリというターミナルエミュレーターがあります。

 

残念なことに Termux: Widget や Termux: Tasker プラグインのような仕組みはありません。

 

なので、作成したシェルスクリプトをウィジェット化してワンタップで実行するとか、プラグインで Tasker や MacroDroid で自動化する、というようなことはできません。

 

 

しかし iSH はパッケージを自由に追加可能な Alpine Linux です。


ターミナルエミュレーター機能に限れば Termux 相当といえるでしょう。


iSH のディレクトリやファイルを iOS のファイルアプリで扱えるので GUI エディターが使え、シェルスクリプトを作成・編集できます。

 

 

iSH とエディター LiquidLogic をインストールします。

 

 

iOS のファイルアプリで iSH のディレクトリにアクセスできますから、いつでもスクリプトを編集できます。

 


 

 

iSH で下記のスクリプト(SwitchBot plug の状態を確認するスクリプト)を作成し、任意のディレクトリに SW_stat.sh という名前で格納し、実行権を与えておきます。

 

ーーーーーーーーーー ここから ーーーーーーーーーー
deviceid
="<デバイスID>"
token="<トークン>"
secret="<クライアントシークレット>"
t=$(date +%s%3N)
nonce=$(uuidgen -r)
sign=$(echo -n ${token}${t}${nonce} | openssl dgst -sha256 -hmac ${secret} -binary | base64)

curl -sS -X GET "https://api.switchbot.net/v1.1/devices/${deviceid}/status"
\
-H "sign: ${sign}" \
-H "t: ${t}" \
-H "nonce: ${nonce}" \
-H "Content-Type: application/json; charset=utf-8" \
-H "Authorization:  ${token}" \
 | cat > ./SW_stat.txt

cat ./SW_stat.txt
echo ""
ーーーーーーーーーー ここまで ーーーーーーーーーー

 

 

これを実行して、SwitchBot plug の状態を確認してみます。

 

そのため iSH で、必要なパッケージをインストールします(echo や cat, base64 は iSH に最初から入っています)。

 

   ~$ apk add uuidgen openssl curl


そして作成したシェルスクリプト SW_stat.sh を実行します。


   ~$ ./SW_stat.sh


結果はエラーでうまくできません。

コマンドラインを一つずつ検証したところ、

 

   t=$(date +%s%3N)

 

この部分でちゃんとミリ秒が得られていないためということがわかりました。

 

改めて date コマンドを検証してみます。

 

   ~$ date +%s%3N
   17366467533N

 

結果は 10桁(秒)に文字列 "3N" がくっついています。


Mac のターミナルで date を検証してみると、上記と同じで 10桁(秒)に文字列 "3N" がくっついてしまいます。

 

 

まずは Mac で brew を使って coreutils をインストールし、GNU 版 date コマンドの gdate でミリ秒が得られました。


   ~$ gdate +%s%3N
   1736647342397

 

Mac と同様に iSH 上で coreutils をインストールして、

 

   ~$ gdate +%s%3N

 

としますが、そんなコマンドはないよと叱られます。

 

ですが coreutils インストールによって、date コマンド自体がミリ秒に対応したことがわかりました。

 

   ~$ date +%s%3N
   1736649967217
 

 

と、13桁のミリ秒を得ました。

 

 

unix time のミリ秒を得るコマンドが Mac と iPhone の iSH で異なるのは、macOS が BSD なのに対して iPhone に入れた iSH が Alpine Linux のためでしょう。

 

 

 

ともあれ date コマンドで unix time ミリ秒が得られるようになりましたので、改めて前記のシェルスクリプトを実行してみます。


   ~$ ./SW_stat.sh

 

curl 実行結果を書き出した SW_stat.txt の内容は下記のように得られ、問題なく処理できました。

 

   ~$ cat SW_stat.txt
   {"statusCode":100,"body":{"version":"V2.0-
   2.0","power":"on","voltage":99,"weight":5.9,
   "electricityOfDay":81,"electricCurrent":95,
   "deviceId":"<デバイス ID>","deviceType":"Plug Mini (JP)",
   "hubDeviceId":"
<デバイス ID>"},"message":"success"}

 

 

iSH が Termux の代替になることを確認できましたが、さてどのように活用しましょうか。

 

 

iSH で作成・保存したシェルスクリプトをショートカット化できると面白いのですが、いまのところできるのかどうかわかっていません(多分、できなさそう (;_;) )。

 

 

 

 

 

 

 

 

2025-01-10

Termux をファイルマネージャーでアクセス ⇨ Android のエディターが使えるようになる

 

Termux のストレージは Termux でしか見えません。


termux-setup-storage コマンドで Androd の内部ストレージを Termux でアクセスできるようになりますが、Android 側からは見えないのです。

 

Android 側からアクセスできるようにするにはいくつかの方法があります。

 

Android 側からアクセスできると Android のエディターアプリから Termux のシェル作成・編集が GUI でできるようになります。

 

Termux でシェル作成・編集は CUI で行うのが基本で、Emacs などは GUI っぽくしてはいますが CUI で、とても操作性がよくありません。

 

 

Android 側からアクセスできるファイルマネージャーをスマホのホーム画面に配置したものが次図です。

 

いくつものファイルマネージャーは必要ないのですが、事例的にインストールしました。

 

実際に使って便利なのは です(これを開くと Termux の home ディレクトリの中身が一発で表示されます)。

 


      ⑥:Acode エディター(コード自動整形機能あり)

      ⑦:Simple Text Editor(コード自動整形機能なし)

 

 

1.Android の Files のアクティビティをショートカット化(

https://bike8615.blogspot.com/2024/11/termux_20.html

Files は Android に標準装備されていますが隠されていて通常は使えませんが、アクティビティをショートカット化すれば使えるようになり、Termux のストレージをアクセスできるようになります

 

 

2.Files by Google を使う(

https://bike8615.blogspot.com/2025/01/termux-android.html

 

 

3.Termux WiKi で紹介のファイルマネージャーを使う 

https://wiki.termux.com/wiki/internal_and_external_storage

この記事内の「Access Termux from a file manager」箇所に2つほど推奨ファイルマネージャーが紹介されています

 

 

調べた限りでは以上が Android 側から Termux のストレージをアクセスできるファイルマネージャーです。

 

 

Android 側からファイルマネージャーで Termux のストレージをアクセスできると、Google Play Store からインストールしたエディターで Termux のシェルを作成・編集できます。

 

 

冒頭の画面コピーにはエディターを2つインストールしていますが、Termux で使うのは Acode で、Simple Text Editor の方はほとんど使いません。

 

 

さらに Acode や Simple Text Editor から Termux のディレクトリやファイルが直接アクセス可能になります。


エディターから新規にシェルを作成してファイルマネージャーを経由せずに任意の Termux のディレクトリへ格納でき、作成したシェルの編集時にファイルマネージャーを経由せずに開くことも可能になるのです。


 

次の画面コピーは Acode から直接に "SW_stat.sh" という作成済みのシェルを開いた画面です。

 


 

 

同様に Simple Text Editor から直接 Termux のファイル(シェル)を開き、編集することもできます。

 

 

 

 

 

 

 

 

2025-01-08

Termux のディレクトリとファイル操作を Android アプリで可能にする

 

下記記事で特別なファイラーをショートカット化すれば扱えるようになる、と紹介しました。

 

Termux のディレクトリやファイルを Android 側でも操作できるようにする

 

記事では、Android のドロワーにも現れず、ホーム画面に配置できない隠されている特別な標準の「ファイル」のアクティビティをショートカット化して Android のホーム画面に配置すれば操作可能になるとしました。

 

 

今回 Files by Google でも扱えることを発見しました。

このアプリを開くと次画面のようになります。

 



 

一番下に「内部ストレージ」と「その他のストレージを参照」が表示されますが「その他のストレージを参照」 をタップすると次画面になります。

 

 


 

「バグレポート」という箇所をタップします。

「システムトレース」が表示される機種(?)もあります。


その場合はどちらをタップしても構いません。

 


 

 

現れた画面で左上の 部分をタップすると次画面になります。

 


 

一番下にある「>_ Termux 空き容量: 92.62GB」という箇所をタップします。

 

Termux の home ディレクトリ一覧が現れますので、操作したいディレクトリをタップすればアクセスできます。

 


 

 

「ファイル」をショートカット化した場合に比べて少し手順がかかりますが、Termux のディレクトリやファイルを操作できるようになります。

 

 

Termux は Android を root 化しなくても Linux 環境を扱えますし、各種のパッケージのインストール、コマンド利用やシェル作成・編集が可能になります。

 

一方、Termux 側からコマンドラインで Androiud の内部ストレージ: "sdカード" は操作できますが(termux-setup-storage 実行が必要です)、Android 側からは Termux のディレクトリやファイルは見れません。

 

見れるようにする方法が本記事や、冒頭の記事に記載した方法があるのですが、これらの方法はほとんど紹介されていません。

 

本記事で紹介の Files by Google による方法は多分ほかでは紹介されていないと思います。

 

 

Termux に詳しい方でも Android 側からは操作できない、としている方々が多いようです。

 

 

「ファイル」ショートカットによって Termux のファイルが Android 側からも操作できるようになると、Termux のシェル作成・編集にエディターアプリが使えるようになります。

 

私は Simple Text Editor(無料) と Acode(F-Droid 版は無料)を使っています。

 

前者は コード自動整形機能はありませんが、後者には備わっています。

 

 

 

Termux の CUI によって vim や nano などで編集することに比べて、Android のエディターアプリにより GUI で格段に操作性が向上します。

 

また Gboard 入力で日本語も入力できます。