Category: Buster

Debian/Ubuntuでawkを切り替える

Debian等でのインストール直後のawkは mawk が導入されます.
Debianのパッケージでは他にGNU awk(パッケージ名 gawk ), The One True Awk(パッケージ名 original-awk )というものもあります.*BSDなどでよく見る nawk もあるように見えますが,シンボリックリンクだけのようです.
(他にもあるかもしれない?)

mawk は初期状態で入っていて軽量.GNU awk はmawkに比べて多機能で既定値では導入されませんが, byobu などが依存を求めるので入っている人も多いと思います.

複数のawkパッケージが導入されているときに awk と実行したときは update-alternatives で管理されたシンボリックリンク先のいずれかのawkが実行されます.これを切り替えてみます.

cpu情報を表示するcpufetch

cpufetchというscreenfetchインスパイアな感じのcpu情報表示ツールを見かけたので試してみました.

$ git clone https://github.com/Dr-Noob/cpufetch
$ cd cpufetch
$ make
$ ./cpufetch -s retro

                               ################
                       #######                #######
                  ####                              ####
              ###                                     ####    Name:              Intel(R) Core(TM) i5-3320M CPU @ 2.60GHz
         ###                                             ###  Microarchitecture: Ivy Bridge
         ###                                             ###  Technology:        22nm
      #                    ###                ###        ###  Max Frequency:     3.300 GHz
    ##   ###   #########   ######   ######    ###        ###  Cores:             2 cores (4 threads)
   ##    ###   ###    ###  ###    ####  ####  ###        ###  AVX:               AVX
  ##     ###   ###    ###  ###    ###    ###  ###       ###   FMA:               No
 ##      ###   ###    ###  ###    ##########  ###     ####    L1i Size:          32KB (64KB Total)
 ##      ###   ###    ###  ###    ###         ###   #####     L1d Size:          32KB (64KB Total)
 ##       ##   ###    ###   #####  #########   ##  ###        L2 Size:           256KB (512KB Total)
 ###                                                          L3 Size:           3MB
  ###                                                         Peak Performance:  52.80 GFLOP/s
  ####                                        ####
    #####                               ##########
      ##########               ################
          ###############################

標準のスタイルでテキストで貼り付けると真っ白になるので retro です.通常の実行結果は以下に.

続きを読む

コマンドライン標準入力からあいまい検索が出来る「pick」

コマンドラインの標準入力をあいまい検索してその結果を主治力出来るpickというコマンドを知ったので試してみました.

たくさんの環境パッケージがあります.今回はDebian sid amd64とRaspberry Pi OS buster armhfで pick パッケージを導入しました.

$ sudo apt install pick (1)
$ ls ~/Downloads/*.pdf | wc -l (2)
181
$ ls ~/Downloads/*.pdf | pick | xargs -I{} xpdf "{}" (3)
rpi (4)
/home/matoken/Downloads/rpi_DATA_CM_3p0.pdf
/home/matoken/Downloads/rpi_MECH_3b_1p2.pdf
/home/matoken/Downloads/RPi-Camera-User-Manual.pdf
/home/matoken/Downloads/rpi_SCH_3b_1p2_reduced.pdf
/home/matoken/Downloads/rpi_SCH_4b_4p0_reduced.pdf
/home/matoken/Downloads/rpi_SCH_ZeroW_1p1_reduced.pdf
/home/matoken/Downloads/RPi_Pi Pico_Digital Edition.pdf
  1. pick パッケージ導入
  2. pdfファイルがたくさんある
  3. lsの結果をpickを挟んでxpdfに渡す
  4. 「rpi」とキーワードを入力することで絞り込まれる

pick 01

上下カーソル入力で結果を選択,Enterで確定.確定された行はSTDOUTに出力され,今回の例では xpdf で開かれる.

コマンド結果が多くて grep を繋いでいくみたいなときに pick を使うとインタラクティブに絞り込まれたりしてわかりやすいです.

似たものに sysboxchoose-stdin というものもあります.

環境1
$ dpkg-query -W pick
pick    2.0.2-1.1
$ lsb_release -dr
Description:    Debian GNU/Linux bullseye/sid
Release:        unstable
$ uname -m
x86_64
環境2
$ dpkg-query -W pick
pick    2.0.2-1
$ lsb_release -dr
Description:    Raspbian GNU/Linux 10 (buster)
Release:        10
$ uname -m
armv7l
$ cat /proc/device-tree/model ;echo
Raspberry Pi 3 Model B Rev 1.2

盆栽楽しい

cbonsai

盆栽が表示できるアプリです.

sourceとx86_64用の.debがあります.armhf環境でsourceからbuildしてみました.

$ sudo apt install libncurses-dev build-essential
$ git clone https://gitlab.com/jallbrit/cbonsai
$ cd cbonsai
$ make
$ install ./cbonsai ~/bin/

いくつかの実行例です.

$ cbonsai (1)
$ cbonsai -p (2)
$ cbonsai -l (3)
$ cbonsai -l -t 0.01 (4)
$ cbonsai -c '<>' (5)
$ cbonsai -m "hello BONSAI" (6)
$ cbonsai -i -w1 (7)
  1. 盆栽を表示(なにかキー入力で終了)
  2. 盆栽をプリントして終了
  3. ライブモード
  4. ライブモードで速度を1/3に(既定値0.03で単位は秒)
  5. 葉っぱを変更
  6. メッセージを表示(マルチバイト文字は不可)
  7. 無限に表示,間隔を1秒間隔に(既定値は4.00秒)

楽しいです🌳

ログイン時に盆栽とfortuneのメッセージを表示したいときはこんな感じで.

$ echo 'cbonsai -p -m "`fortune`"' >> ~/.profile

環境
$ git log -1
commit 15e19580ddc58741291386000076928b2e591ef2 (HEAD -> master, origin/master, origin/HEAD)
Author: John A <jallbritten6@gmail.com>
Date:   Thu Mar 4 10:37:32 2021 -0500

    Update install instructions and add bashrc notice

$ dpkg-query -W libncurses-dev build-essential
build-essential 12.6
libncurses-dev:armhf    6.1+20181013-2+deb10u2
$ lsb_release -dr
Description:    Raspbian GNU/Linux 10 (buster)
Release:        10
$ arch
armv7l
$ cat /proc/device-tree/model && echo
Raspberry Pi 3 Model B Rev 1.2

いくつかの”sl”コマンドを試す

ノーマル?sl

なんとなくジョークプログラムのslを導入しました.

$ sudo apt install sl

sl pkg

しかし物足りません🤔

Izumiさん改造版

昔はSunOS上でとても長い編成だったり通り過ぎて遮断器が上がったかと思うとまた下がって折り返したりするpatchを当てていました.探してみると恐らくこちらのもの.

しかしpatchがリンク切れ.Wayback Machineにも見つかりません.

検索するとこちらのページを発見.patch適用済のものをGitHubにアップロードされています.こちらを試してみました.

$ sudo apt build-dep sl (1)
$ git clone https://github.com/gmkou/sl (2)
$ cd sl
$ make (3)
$ install ./sl ~/bin/ (4)
$ which sl (5)
/home/matoken/bin/sl
$ sl
  1. slのビルドに必要なパッケージを導入
  2. sourceをclone
  3. make
  4. 適当な場所にインストール
  5. slのパスを確認

sl long

30両くらいのなが〜いslも出現するようになりました😻これでlsのTypo矯正が捗る……かもしれません.

ミラー版sl

こちらのslはミラーバージョンでlsの結果を反転させて表示します.これも楽しい

$ /tmp/sl -l
04                                                         latot
dm.ETALPMET_EUSSI 70:60 2  raM 044  nekotam nekotam 1 --r--r-wr-
elifekaM          70:60 2  raM 868  nekotam nekotam 1 --r--r-wr-
dm.EMDAER         70:60 2  raM 0351 nekotam nekotam 1 --r--r-wr-
itg               70:60 2  raM 0079 nekotam nekotam 1 x-rx-rxwr-
6.itg             70:60 2  raM 8001 nekotam nekotam 1 --r--r-wr-
c.itg             70:60 2  raM 2258 nekotam nekotam 1 --r--r-wr-
$ ls -l
total 40
-rw-r--r-- 1 matoken matoken  440 Mar  2 06:07 ISSUE_TEMPLATE.md
-rw-r--r-- 1 matoken matoken  868 Mar  2 06:07 Makefile
-rw-r--r-- 1 matoken matoken 1530 Mar  2 06:07 README.md
-rwxr-xr-x 1 matoken matoken 9700 Mar  2 06:07 gti
-rw-r--r-- 1 matoken matoken 1008 Mar  2 06:07 gti.6
-rw-r--r-- 1 matoken matoken 8522 Mar  2 06:07 gti.c

おまけ)gti

そういえばslインスパイアなgitに対するgtiというものもあります.これはgitと打とうとしてgtiと入力してしまったとき車が走っていきます🚗

楽しいですね.

$ git clone https://github.com/rwos/gti
$ cd gti
$ make
$ install ./gti ~/bin/
$ gti

sl gti

環境

$ lsb_release -dr
Description:    Raspbian GNU/Linux 10 (buster)
Release:        10
$ uname -a
Linux raspberrypi 5.10.11-v7+ #1399 SMP Thu Jan 28 12:06:05 GMT 2021 armv7l GNU/Linux
$ cat /proc/device-tree/model ;echo
Raspberry Pi 3 Model B Rev 1.2

GitHub.comのリポジトリの特定のディレクトリ以下をダウンロードできる「GitHub clone」

大きなGitリポジトリをcloneすると時間がかかります.最新のものだけが欲しい場合は --depth オプションがありますが,リポジトリの一部のディレクトリ以下だけが欲しい時には使えません.そういうときにGitHub cloneを使うと,特定のディレクトリ以下だけをダウンロードできて便利そうです.

少し試してみました.

$ pip3 install git+git://github.com/HR/github-clone#egg=ghclone (1)
$ ghclone (2)
Usage:
  ghclone <url> [-t | --token=<token>]
  ghclone (-h | --help)
  ghclone (-v | --version)
$ ghclone https://github.com/torvalds/linux/tree/master/tools/usb/usbip (3)
Cloning into 'usbip'...
done.
$ cd usbip
$ ls -A (4)
.gitignore  AUTHORS  COPYING  INSTALL  Makefile.am  README  autogen.sh  cleanup.sh  configure.ac  doc  libsrc  src  vudc
$ git status (5)
fatal: not a git repository (or any of the parent directories): .git
$ cd ..
$ ghclone https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/usb (6)
Invalid GitHub URI
  1. pipで導入する(もしPATHが通ってなければ ~/.local/bin を加える)
  2. USAGE
  3. Linux Kernelの一部だけをダウンロード
  4. ダウンロード内容確認
  5. Git管理はされていない
  6. GitHub以外のGitリポジトリに対して実行すると失敗する

GitHub.comのAPIを利用しているのでGitHub.com以外では使えませんが便利そうです.

似たものにBitBacketで同様のことができる,「bb-clone」というものもあるようです.

環境
$ ghclone -v
1.2.0
$ dpkg-query -W git python3-pip python3
git     1:2.20.1-2+deb10u3
python3 3.7.3-1
python3-pip     18.1-5+rpt1
$ lsb_release -dr
Description:    Raspbian GNU/Linux 10 (buster)
Release:        10
$ uname -a
Linux raspberrypi 5.10.11-v7+ #1399 SMP Thu Jan 28 12:06:05 GMT 2021 armv7l GNU/Linux
$ cat /proc/device-tree/model ;echo
Raspberry Pi 3 Model B Rev 1.2

センサーのログをNextcloudのSensorloggerで記録してみる

この記事は 日本Androidの会秋葉原支部ロボット部 Advent Calendar 2020 の20日分の記事です.
日本Androidの会秋葉原支部ロボット部は現在月に一回勉強会を行い様々な話題で盛り上がっています.
次の勉強会はちょうど今日(20日)です.興味のある方は覗いてみてください.

センサーのログなどをアップロードするのに色々なwebサービスを使ったり,Googleスプレッドシートに書いたりしています.
便利なんだけどロックインになるのは嫌だなって思ったりします.

Nextcloudというファイル共有サービス+αなOSSがあります.アプリケーションを追加して機能を増やすことが出来ます.例えばテレビ電話や,オンラインオフィスとか,マップサービスとか様々なアプリがあります.
これを個人的に立てて便利に使っています

この中のアプリを眺めているとSensorloggerというセンサーのログを保存できそうなものを見つけたので試してみました.

まずNextcloudですが,とりあえず試すだけならsnapを利用するのがお手軽です.Raspberry Pi + Raspberry Pi OSなどでもOKです.

Debian sid amd64/Ubuntu 20.04 LTS/Raspberry Pi OS armhfでは以下の手順でOKでした.

$ sudo apt update && sudo apt upgrade   (1)
$ sudo apt install snapd    (2)
$ sudo snap install nextcloud   (3)
  1. システムのパッケージを最新にする
  2. snapを使えるように snapd パッケージを導入
  3. snapでnextcloudを導入

10分位待つと導入が終わります.ウェブブラウザにIPアドレスを入力するとセットアップ画面が表示されるので管理者ID/PASSWORDを設定します.

これでとりあえず使えるようになったと思います.

この後Sensorloggerを導入します.
管理者権限のアカウントでNextcloudの右上のメニューから「アプリ」を開きます.

20201219 20:12:45 2014278

次に上の検索バーに「Sensorlogger」とかの文字列で検索して「有効」ボタンを押して導入します.

20201219 20:12:42 2017785

Tip
Nextcloudのアプリケーションはコマンドラインから導入することも出来ます.
$ sudo -u www-data occ app:install sensorlogger #通常導入した場合
$ sudo /snap/bin/nextcloud.occ app:install sensorlogger で導入した場合

ここからは一般ユーザでOKです.

Nextcloudの上部から「Sensorlogger」のアイコンをクリックするとSensorloggerの画面が表示されます.

20201219 20:12:03 2021911

はじめはデータがないのでまっさらです.「Device」辺りでデバイスの登録をするのかな?と思いましたが出来ません.
「Read SensorLogger Wiki Devices」と書かれているのでWikiを参照してみます.

データを送ると自動的にデバイスが出来るようです.Simple, Complexの2種類のデータタイプがあるようです.Simpleは温度,湿度のようでとりあえずこれを試してみます.

以下の辺りから post.php を持ってきて使います.このscriptはダミーのランダムな温度と湿度データを作ってSensourloggerにデータを投げます.

何箇所か書き換えます.
* $url = ` を自分のNextcloudのURLに変更します.
* `$array = array("deviceId" ⇒
uuidgen コマンドなどで生成したUUIDに変更します.
* $username = をNextcloudの自分のユーザーに変更します.
* $token = に「設定」「セキュリティ」ページの「デバイスとセッション」の一番下の「新しいアプリパスワードを作成」で作成したトークンに修正します.

そしてphpとphp-curlが必要なので導入します.

Debian sid amd64/Ubuntu 20.04 LTS/Raspberry Pi OS armhfでの例
$ sudo apt install php-cli php-curl

この状態で post.php を実行して成功すると以下のようなメッセージが帰ってきます.

$ php ./post.php
{"success":true,"message":"Sensor Log successfully stored","data":null}

Sensorloggerのページの List を見るとエータがアップロードされているのが解ります :)

手動で実行するのは大変なのでcrontabにこんな感じで登録してみます.5分に一回データを送信します.

$ crontab -e (1)
$ crontab -l | grep post.php (2)
*/5 * * * *     php ~/tmp/post.php 2&>1 > ~/tmp/post.php.log
  1. crontabの編集
  2. crontabに登録されたか確認

同様にRaspberry Piの温度も送ってみます.温度の $temperature を以下のような感じで書き換えて,UUIDも書き換えるとOK.これもcrontabに登録します.

    $temperature = system( '/opt/vc/bin/vcgencmd measure_temp | awk -F "[=\']" \'{print $2 }\' | tr -d \'\n\'' );

しばらく動かしてからダッシュボードを設定するとこんな感じのチャートが表示できました.

20201219 20:12:13 2035392

密集してよくわからない部分はマウスドラッグで矩形選択するとその部分がズームされます.

20201219 22:12:30 2180945

という感じでとりあえず動きました.ドキュメントが未だ充実していな買ったり使い勝手も悪いですが最低限の機能はあるかなという感じです.
興味があったら試してみてください.
若しくはおすすめのアプリやサービスを教えてください.

Raspberry Pi の温度管理をソフトウェアで頑張る

この記事は日本Androidの会秋葉原支部ロボット部 Advent Calendar 2020 の12/07分の記事です.

内容は 日本Androidの会秋葉原支部ロボット部 第96回勉強会 で発表した内容を加筆修正したものです.

はじめに

Raspberry Pi という英国発の教育向けとして2012年に発売された安価なシングルボードコンピュータがあります.教育向けとして発売されましたが趣味にもよく使われています.OSは標準ではLinux(DebianベースのRaspberry Pi OS)が採用されています.

私はもっぱら省電力のLinuxマシンとして使うことが多いです.

トラブル

今夏空調のない部屋の自宅サーバの横でRaspberry Pi 3 model B + Raspberry Pi OS arm64(β)で計算をさせていたのですが,しばらく動かしていると固まるようになりました.

再起動すればしばらく動きますがしばらくするとやはり固まります.これをどうにか出来ないかと調べてみました.

ログの取得

まずはログを録ってみます.

crontabで1分毎に情報を記録
* * * * *       printf "`date +\%s`,`cat /sys/class/thermal/thermal_zone0/temp`,`echo "obase=2; ibase=16; \`vcgencmd get_throttled | cut -f2 -dx\`" | bc`,`vcgencmd measure_clock arm|cut -f2 -d=`\n" >> ~/.temp.log

内容はこんな感じです.(外気温度も録ればよかった)

UNIX Time
date +%s
SoC温度
/sys/class/thermal/thermal_zone0/temp
スロットリング周りのフラグ
vcgencmd get_throttled
arm周波数
vcgencmd measure_clock arm

ログがファイルに書かれる間にフリーズしてデータが失われるのを防ぐために /etc/fstab のマウントオプションに sync オプションも付けておきます.(再起動かremountで反映)

ログを取得している状態で負荷を掛けます.今回は /dev/urandom をcatすることで計算させました.今回のRaspberry Pi 3 model Bは4coreあるので4つ動かしています.

今回のテストで使った負荷(いつもはvanity address/vttとかとか)
$ cat /dev/urandom > /dev/null &
$ cat /dev/urandom > /dev/null &
$ cat /dev/urandom > /dev/null &
$ cat /dev/urandom > /dev/null &

熱が原因?

しばらく動かしてRaspberry Piが固まった後にログを確認してみます.
SoCの温度が85度を何度か記録した後に固まっているようです.
85度というのはRaspberry Pi OSでの標準のSoC制限温度のようです.この温度の5度前(標準では80度)からサーマルスロットリングが始まるようです.

サーマルスロットリングでクロックが下がって温度が下がれば問題無さそうだけど80度からクロックが下がっても85度を超えて固まってしまっているようです.
ベータ版のRaspberry Pi OS amd64を使っているせいかもしれないと思い,標準のRaspberry Pi OS armhf(32bit)版に変更して同様に試してみましたが同様の動きのようです.

正攻法としてはヒートシンク,ファンの増設や空調を入れるとよさそうですが,金欠なのでとりあえずソフトだけでどうにか出来ないかと試しました.

SoC制限温度を下げる

まずSoCの制限温度ですが,公式フォーラムで70度以下にしたほうがいいという書き込みを見かけました.逆に100度でも大丈夫という人も居るのですが安全側の70度にしてみます.

この設定は /boot/config.txt でパラメータを設定できます.以下は70度に設定たときの例です.この状態で再起動すると反映されます.

temp_limit=70

再起動後以下のコマンドで設定が反映されているか確認が出来ます.

$ vcgencmd get_config int | grep ^temp_limit=
temp_limit=70

この状態で負荷を掛けると70度を越えるくらいで固まりました.やはり制限温度を越えると固まってい舞うようです.

SoCの最大周波数を下げてみる

Raspberry Pi 3 model B のSoCは最大周波数1.2GHzです.これを下げてみます.

/boot/config.txtarm_freq= で設定できます.以下は800MHzに設定したときの例です.再起動で反映されます.

arm_freq=800

再起動後に設定が反映されているか確認します.

$ vcgencmd get_config int | grep ^arm_freq=
arm_freq=800

この状態で負荷を掛けるとやはり固まります.まあサーマルスロットリングが効いても固まるので仕方がない感じです.

SoCの最小周波数を下げてみる(これが効くのでは?)

次にSoC最小周波数を下げてみます.既定値は600MHzで,サーマルスロットリングでもここまで下がっているのでこれを更に下げると温度が下がりそうな気がします.

/boot/config.txtarm_freq_min= で設定できます.以下は400MHzに設定したときの例です.再起動で反映されます.

arm_freq_min=400

しかし再起動後に確認してみると600MHzより下には設定できないみたいで600MHzになってしまいます.

$ vcgencmd get_config int | grep ^arm_freq_min=
arm_freq_min=600

この状態で負荷を掛けるとやはり600Mhzまでしか下がらず固まります.

残念ながらRaspberry Pi のスロットリングでは無理そうです.

maxcpusでコアを制限してみる

Linuxのブートパラメータで maxcpus を指定することでコアを制限できます.Raspberry Pi の場合は /boot/cmdline.txt で設定できます.

設定後以下のコマンドで確認できます.

$ grep -o -E 'maxcpus=.{0,9} ' /proc/cmdline
maxcpus=1
$ grep ^processor /proc/cpuinfo | wc -l
1

これでCPU core1津で動作しています.しかし最大周波数を600MHzかつ1coreでも同様にフリーズしてしまいました.

cpufreqでクロック制御

IntelCPUのNotePCなどではcoufreqを使ってこのあたりの制御をするのですが,これでも600mHzより下には下げられないようで駄目でした.

LimitCPUで指定プロセスの制限を行う

LimitCPUは指定プロセスを監視し,CPU利用率や%で制限するプログラムです.Linux, MacOS, *BSDなどのUNIX-Likesystemで利用できます.
Raspberry Pi OSではcpulimitパッケージとしてパッケージングされており,コマンドもcoulimitです.

cpulimitの導入
$ sudo apt install cpulimit

cpulimitコマンドに制限したいプロセスIDやプロセス名と制限を指定することで動作します.

cat からはじまるプロセスを50%に制限
$ pgrep ^cat | xargs -n1 -I{} sh -c "cpulimit -p {} -l 50 -v &"

cpulimitで50%に制限してみたt頃温度が下がるのを確認できました.数日動かしても固まらなくなったようです.
定期的にSoCの温度を確認して制限を変更していくと良さそうでうs.

LimitCPUはCPUlimitの開発が止まった後のフォークですが,その後CPUlimitが新しく開発が始まっているようです.詳細は以下のページを参照してください.

cgroupでCPUリソース制限(未確認)

LimitCPUが効いたので恐らくcgroupでのCPUリソース制限でも大丈夫そうです.(未確認)

おわりに

現在は気温も下がり制限などしなくても問題ありません.でもきっと来夏にまた起こると思うのでそこでまた確認するつもりです.

しかし,今回の解決方法はCPUのリソースを制限して温度を下げて居るので計算量は減っています.空調を入れたりCPUファンを導入するのが正攻法になるのかなと思います.
CPUファンはサードパーティーから各種発売されているのでそれらを使うかDIYする感じになると思います.

そういえば最近Raspberry Pi OSの設定コマンドの raspi-config の中に Set behaviour of GPIO fan というメニューが出来たり,Raspberry Pi 4には公式のCPUファンが発売されているのでこれらを使うのが良さそうです.

Raspberry Pi OS/Debian/Ubuntuでの既定のPython切り替え

最近使うPythonアプリはPython3が多くなっています.Python2のEoLが迫っているので正しいのですが,手元の環境では python コマンドは python2 に向いています.python3 コマンドを叩けばいいのですが,これを python3 に向けられないかなと試してみました.

Raspberry Pi OS arm64(busterベース)でのPython確認してみます.python コマンドは python2.7 を呼ぶようになっています.

$ python --version
Python 2.7.16
$ ls -l `which python`
lrwxrwxrwx 1 root root 7  3月  5  2019 /usr/bin/python -> python2
$ ls -l `which python2`
lrwxrwxrwx 1 root root 9  3月  5  2019 /usr/bin/python2 -> python2.7
$ ls -l `which python3`
lrwxrwxrwx 1 root root 9  3月 26  2019 /usr/bin/python3 -> python3.7

update-alternatives で管理されてるのかな?と思いましたが設定がなさそうです.

$ update-alternatives --get-selections|grep -i ^python

update-alternatives を手動で設定してみます.
これで python コマンドが python3.7 を呼ぶようになりました.

$ sudo update-alternatives --install /usr/bin/python python /usr/bin/python2.7 1
update-alternatives: /usr/bin/python (python) を提供するために自動モードで /usr/bin/python2.7 を使います
$ sudo update-alternatives --install /usr/bin/python python /usr/bin/python3.7 2
update-alternatives: /usr/bin/python (python) を提供するために自動モードで /usr/bin/python3.7 を使います
$ ls -l `which python`
lrwxrwxrwx 1 root root 24  7月 28 08:47 /usr/bin/python -> /etc/alternatives/python
$ python --version
Python 3.7.3
$ update-alternatives --query python
Name: python
Link: /usr/bin/python
Status: auto
Best: /usr/bin/python3.7
Value: /usr/bin/python3.7

Alternative: /usr/bin/python2.7
Priority: 1

Alternative: /usr/bin/python3.7
Priority: 2

切り替えたいときはこんな感じで選択肢なおせばok.

$ sudo update-alternatives --config python
alternative python (/usr/bin/python を提供) には 2 個の選択肢があります。

  選択肢    パス              優先度  状態
------------------------------------------------------------
* 0            /usr/bin/python3.7   2         自動モード
  1            /usr/bin/python2.7   1         手動モード
  2            /usr/bin/python3.7   2         手動モード

現在の選択 [*] を保持するには <Enter>、さもなければ選択肢の番号のキーを押してください:

Debian asid amd64, Ubuntu 20.04 LTS amd64 でも設定してみました.

Debian sid amd64
$ update-alternatives --query python
Name: python
Link: /usr/bin/python
Status: auto
Best: /usr/bin/python3.8
Value: /usr/bin/python3.8

Alternative: /usr/bin/python2.7
Priority: 1

Alternative: /usr/bin/python3.7
Priority: 2

Alternative: /usr/bin/python3.8
Priority: 3
Ubuntu 20,04 LTS amd64
$ update-alternatives --query python
Name: python
Link: /usr/bin/python
Status: auto
Best: /usr/bin/python3.8
Value: /usr/bin/python3.8

Alternative: /usr/bin/python2.7
Priority: 1

Alternative: /usr/bin/python3.5
Priority: 2

Alternative: /usr/bin/python3.8
Priority: 3

てことで python コマンドが python3 になりました.しかしシステムワイドな設定なのでシステムのプログラムなどで問題が出るかもしれないですね.
問題が起こったらpython2に戻しましょう.

Rasoberry Pi OS amd64
$ dpkg-query -W python python3
python  2.7.16-1
python3 3.7.3-1
$ lsb_release -dr
Description:    Debian GNU/Linux 10 (buster)
Release:        10
$ uname -m
aarch64
$ cat /proc/device-tree/model&&echo
Raspberry Pi 3 Model B Rev 1.2
Debian sid amd64
$ dpkg-query -W python python3 python3.7
python  2.7.17-2
python3 3.8.2-3
python3.7       3.7.7-1+b1
$ lsb_release -dr
Description:    Debian GNU/Linux bullseye/sid
Release:        unstable
$ uname -m
x86_64
Ubuntu 20.04 LTS amd64
$ dpkg-query -W python python3 python3.7
python  2.7.17-1
python3 3.8.2-0ubuntu2
python3.7
$ lsb_release -dr
Description:    Ubuntu 20.04.1 LTS
Release:        20.04
$ uname -m
x86_64

Sipeed Lichee Nanoでhello world

2020-07-23低レベル勉強会に参加しました.Zoom.usでの開催でした.

内容はLinux名刺的なものを開発しようという内容で,リファレンスとしてSDカードサイズの小さなLinuxの動作するarmコンピュータのSipeed Lichee Nanoを使いました.

欲しい場合は1000円ちょいくらいからで入手できそうです.

Lichee Nanoを持っていない人はリモートで触れるようにしてあったので持っていない私も楽しめました.

このリモート開発の仕組みはLichee NanoとRaspberry PiをUSB経由のUARTで接続し,Raspberry PiでGNU screenを起動,ssh経由でGNU screenに繋いで操作という感じです.
GNU screenをGotty等にするとウェブブラウザで参加できてちょっと便利かもと思ったりも.(GoTTYは開発止まってるように見えるから別のもののほうがいいかもしれない)

Lichee Nanoで何かを動かしたい.armだけどarmhf動くのかな?とりあえずなにか転送して動かしてみようと.

とりあえずDebianのarmhfバイナリをuuencodeしてコピペで転送してみます.これが動けばDebianのパッケージ群が利用できるかもだけど…….

まずは簡単そうなfortuneを試します.

Debian sidでfortune-modパッケージのarmhfバイナリパッケージをダウンロードして展開(add archtecture armhfしてある環境)
$ apt download -t armhf fortune-mod
$ unar fortune-mod_1.99.1-7+b1_armhf.deb
$ cd fortune-mod_1.99.1-7+b1_armhf
$ tar xf data.tar.xz
$ cd usr/games

Lichee Nanoはserialで接続されていて,Internetには繋がっていないのでバイナリファイルの転送にはuudecode/uuencodeを使いました.久々です.
手元のGNU sharutils 4.15.2のuudecodeにはbase64を使う -m, --base64 があるので良さそう.と思ったけどLichee Nanoの方はbusyboxのもので非対応でした.

ローカル端末で圧縮してuuencodeしてクリップボードへ
$ gzip -c fortune | uuencode fortune.gz > fortune.gz.uu
$ cat fortune.gz.uu | xclip
リモートで伸張して解凍
# cat | uudecode    #ここでクリップボードから貼り付け
# zcat fortune.gz > fortune
# rm fortune.gz

そして…​…​

# ./fortune
-sh: ./fortune: not found
# ldd ./fortune
checking sub-depends for 'not found'
checking sub-depends for '/lib/libc.so.6'
/lib/ld-linux.so.3 (0xb6fa0000)
librecode.so.0 => not found (0x00000000)
libc.so.6 => /lib/libc.so.6 (0x00000000)
/lib/ld-linux.so.3 => /lib/ld-linux.so.3 (0x00000000)

これを動かすのはダイナミックリンクされているものを用意してあげないといけないのでストレージの容量的に難しいですね.

ここではgzipで圧縮しましたが,Lichee Nanoのbusyboxにxzがありました.gzipよりxzにしたほうが小さくなりますね.試してみるとこんな感じでした.$ xz -c fortune | uuencode fortune.xz > fortune.xz.uu

サイズ比較
-rw-r--r-- 1 matoken matoken 22368 Jul 23 15:11 fortune #元ファイル
-rw-r--r-- 1 matoken matoken 30844 Jul 23 14:58 fortune.uu 
-rw-r--r-- 1 matoken matoken 14975 Jul 23 15:08 fortune.gz.uu  + uudecode
-rw-r--r-- 1 matoken matoken 13047 Jul 23 15:47 fortune.xz.uu  + uudecode

そういえばあまり有名ではないですがbasE91なんてものもあります.base64よりサイズが小さくなりますが導入からやらないといけないのでちょっと面倒.

Hello worldを試してみます.適当にプログラムを用意してスタティックリンクでコンパイルしてみます.

$ cat hello.c
 <stdio.h>
int
main(void)
{
    printf("Hello, world!\n");
    return 0;
}
$ gcc -static ./hello.c
$ ./a.out
Hello, world!
$ ls -l a.out
-rwxr-xr-x 1 pi pi 571120 7月 23 16:18 a.out

でかい…​…​

とりあえずでかいのはおいといてこれだとarm64なので動くはずがない.ということでクロスコンパイル環境を用意します.

今回試したホストはDebian sid amd64/Ubuntu 20.04 LTS arm64/Raspberry Pi OS arm64です.いずれも同じ手順でOKでした.

crossbuild-essential-<arch> パッケージで各種アーキテクチャの環境が導入できるようです.

$ apt-cache search crossbuild-essential-
crossbuild-essential-amd64 - Informational list of cross-build-essential packages
crossbuild-essential-arm64 - Informational list of cross-build-essential packages
crossbuild-essential-armel - Informational list of cross-build-essential packages
crossbuild-essential-armhf - Informational list of cross-build-essential packages
crossbuild-essential-i386 - Informational list of cross-build-essential packages
crossbuild-essential-powerpc - Informational list of cross-build-essential packages
crossbuild-essential-ppc64el - Informational list of cross-build-essential packages
crossbuild-essential-s390x - Informational list of cross-build-essential packages
crossbuild-essential-mips - Informational list of cross-build-essential packages
crossbuild-essential-mips64 - Informational list of cross-build-essential packages
crossbuild-essential-mips64el - Informational list of cross-build-essential packages
crossbuild-essential-mips64r6 - Informational list of cross-build-essential packages
crossbuild-essential-mips64r6el - Informational list of cross-build-essential packages
crossbuild-essential-mipsel - Informational list of cross-build-essential packages
crossbuild-essential-mipsr6 - Informational list of cross-build-essential packages
crossbuild-essential-mipsr6el - Informational list of cross-build-essential packages

沢山あります.今回はarmlf/armhfの crossbuild-essential-armel, crossbuild-essential-armhf を導入しました.

$ sudo apt install crossbuild-essential-armel crossbuild-essential-armhf

gccだけでいい場合はarmlfは gcc-arm-linux-gnueabi,armhfは gcc-arm-linux-gnueabihf だけでOKです.

まずは arm-linux-gnueabihf-gcc を使ってarmhfのバイナリを作ります.

$ /usr/bin/arm-linux-gnueabihf-gcc -static ./hello.c
$ strip a.out
$ xz -c a.out | uuencode a.out.xz > a.out.xz.uu

armhfは駄目そうです.

# cat | uudecode
^d
# xzcat ./a.out.xz > ./a.out
# chmod +x ./a.out
# ./a.out
Segmentation fault

次は gcc-arm-linux-gnueabi でarmlfのバイナリを作って試すと動きました.

$ /usr/bin/arm-linux-gnueabi-gcc -static ./hello.c
$ strip a.out
$ xz -c a.out | uuencode a.out.xz > a.out.xz.uu
# cat | uudecode
^d
# xzcat ./a.out.xz > ./a.out
# chmod +x ./a.out
# ./a.out
Hello, world!
# /usr/bin/time -f "%M KB" ./a.out
Hello, world!
2144 KB

この辺りで今回は時間切れ.次回の同じような感じになりそうです.興味のある方は以下のページから.

とりあえずarmelのバイナリが動くようなのがわかったので面白そうな小さなプログラムを試そうかなと思っています.cowsayとか好きなんだけどこれはPerlなので容量的に難しそう.とりあえずfortuneあたりかな?

以前PQI Air PenでやったようにSD cardを用意してそこにDebian armlf環境を展開してchrootとかもできそうです.