Pythonista 3.4 の StaSh で ssh を動かせたので、やったことをまとめます。
おことわり
Pythonista 3 のシェル環境 StaSh で ssh を使用するメリットについては触れません。ssh 接続をしている間は iPhone 本体が通常より熱を持つため、特にその必要が無い限り Termius 等の無料の SSH クライアント専用アプリを使用するのが良いと思います。本記事はむしろ、以前のバージョンの Pythonista 3 と StaSh で動いていたコマンドを、ver. 3.4 で動かす時の参考にしてもらえればと思います。また、再検証はしておらず、残しておいたメモを元に構成しているため、漏れや間違いがある可能性も否めません。
Pythonista 3.4 では、Python 2.7 のコードをそのまま実行することができなくなりました。StaSh に含まれるコマンドは全てが Python 3 に対応しているわけでは無く、ssh コマンド (ssh.py) もその一つです。以前の Pythonista (ver. 3.3 以前) では StaSh 自体を Python 2 環境で実行すれば ssh が実行可能でしたが、今後は Python 2 用コードは Python 3 に変換してあげる必要があります。Pythonista ではツールが用意されていて、スパナアイコンから Python 2 to 3 をタップすると自動変換してくれます。ただ、ssh コマンドは手直しが必要でした。
バージョン情報等
$ version
StaSh v0.8.0
Python 3.10.4 (CPython)
UI stash.system.shui.pythonista_ui
root: ~/Documents/site-packages/stash
core.py: 2023-05-05 18:00:40
SELFUPDATE_TARGET: master
Pythonista 3.4 (340012)
iOS 16.4.1 (64-bit iPhone10,2)
Platform iOS-16.4.1-iPhone10,2-64bit
BIN_PATH:
~/Documents/bin
~/Documents/stash_extensions/bin
~/Documents/site-packages/stash/bin
StaSh は、記事作成時に最新の dev バージョンです (StaSh インストール方法は別記事参照)
やったことひとまとめ
つど必要に応じて (変更箇所を反映させる等) Pythonista の再起動を実施しています。秘密鍵を使用した SSH の設定と、接続時の行数の指定例は過去記事をご参照下さい。
- ~/Documents/site-packages/stash/bin/ssh.py を ~/Documents/stash_extensions/bin/ssh3.py としてコピー
- ssh3.py に対して「Python 2 to 3」を実行 (変更内容はそのまま)
- ssh3.py の関数
vk_tapped
の内部vk.name
を全て int として処理するように書き換え (変更内容は下記) - ~/Documents/site-packages/stash/system/shscreens.py に対して「Python 2 to 3」を実行 (変更内容はそのまま)
- shscreens.py の 541 行目と 576 行目それぞれにある
/
を//
に変更。変更後はこうなります:idx_line, idx_column = idx // (ncolumns + 1), idx % (ncolumns + 1)
- StaSh で
ssh3
を実行
vk_tapped
の変更後はこちら。Python 3 のコードに変換後の行数で、242~262 の部分になります。内容としては、vk.name
を全て vk
にし、'k_tab'
等となっていた部分を対応した数値に置き換えています。この変更により、StaSh のバーチャルキーボードで Tab や Up、CC 等をタップしたときに、SSH 接続先にも正しいキーコード (それぞれタブ、カーソル上、Control + C) が送られるようになります。
def vk_tapped(self, vk):
if vk == 7:
self.send('\t')
elif vk == 0:
self.kc_pressed('C', CTRL_KEY_FLAG)
elif vk == 1:
self.kc_pressed('D', CTRL_KEY_FLAG)
elif vk == 6:
self.kc_pressed('U', CTRL_KEY_FLAG)
elif vk == 9:
self.kc_pressed('Z', CTRL_KEY_FLAG)
elif vk == 2:
self.kc_pressed('UIKeyInputUpArrow', 0)
elif vk == 3:
self.kc_pressed('UIKeyInputDownArrow', 0)
elif vk == 10:
if _stash.terminal.is_editing:
_stash.terminal.end_editing()
else:
_stash.terminal.begin_editing()
出ていたエラーと解決のためのヒント
実際に ssh が動くようになるまでに行った手順としては、上のステップ 3 が最後になります。自分が最初にぶちあたったのは、ステップ 4の shscreens.py を Python 3 に変換した後で、エラーはこちらです:
system/shscreens.py", line 578, in load_pyte_screen
c = pyte_screen.buffer[idx_line][idx_column]
TypeError: list indices must be integers or slices, not float
小数 (float) になっているのが問題と言うことなので、元の idx_line と idx_column を int() で整数にしてから呼び出されるようにしても解決せず、以下ページがヒント (とういか答え) となりました。
My guess would be that stash uses / division for line/column indices. On Python 3 / always produces a float. The fix is simple: replace it with flooring division //.
https://github.com/selectel/pyte/issues/123
ステップ 3 の変更を加える事になった原因のエラーはこちらです:
File "stash_extensions/bin/ssh3.py", line 230, in vk_tapped
if vk.name == 'k_tab':
AttributeError: 'int' object has no attribute 'name'
これは StaSh 自体のコードに関わる内容だと思うんですが、よくわかりません。ここをいじらなくても、SSH セッション自体は張れます。この関数の目的は、押された vk
(=virtual key) に対応したキーコードを SSH 接続先に送るということです。なので、関数直下に print(vk)
を差し込み、SSH 接続した状態で Tab やら CC やらを押して Console に表示される数字に name の値を置き換えていきました。美しい解決方法を探ったのですが諦めました。
さて、そもそも今回 ssh コマンドを動かしてやろうという動機付けになったのは、StaSh の説明の中にあった一文、特に色を付けた部分でした。
StaSh works with both Pythonista 2 and 3, though not all commands support python3. (訳: StaSh は Pythonista 2 でも 3 でも動きますが、全てのコマンドが python3 対応にはなっていません)
https://github.com/ywangd/stash
Image by Stable Diffusion
ここからは本文に関係ありません。今回のアイキャッチ画像は、Mac 用 Stable Diffusion クライアントの Mochi Diffusion で出力した画像に、後から文字を描き足したモノです。 Stable Diffusion を使った場合は、情報を記載するようにします。
Date:
2023年5月6日 22:31:24
Model:
realisticVision-v20_split-einsum
Size:
512 x 512
Include in Image:
cartoon, a young man waring glasses, super happy
Exclude from Image:
Seed:
3826992198
Steps:
20
Guidance Scale:
11.0
Scheduler:
DPM-Solver++
ML Compute Unit:
CPU & Neural Engine