shell

標準入出力を乗っ取ったりしていろいろやる

ちょっと前に .bashrc に追加したやつの紹介。 既に(別の terminal で)動いているプロセスの stdin, stdout, stderr を乗っ取って自分の terminal に 無理矢理つなぐ。 (適当に dotfiles から抜粋) if [ "$#" -ne 1 ]; then echo 'usage: hijack PID' >&2 return 1 fi local tty="$(readlink /proc/self/fd/0)" echo "Info: Connect to $tty" local run_as_root= if command -v sudo &>/dev/null && [ "_$(whoami)" != '_root' ]; then run_as_root=sudo fi local pid="$1" $run_as_root gdb -p "$pid" <<EOF compile code \ unsigned char attrs[3][1024]; \ for (int fd = 0; fd < 3; ++fd) { \ tcgetattr(fd, (struct termios *)attrs[fd]); \ } \ dup2(open("$tty", 0 /* O_RDONLY */), 0); \ dup2(open("$tty", 1 /* O_WRONLY */), 1); \ dup2(open("$tty", 1 /* O_WRONLY */), 2); \ for (int fd = 0; fd < 3; ++fd) { \ tcsetattr(fd, 0 /* TCSADRAIN */, (struct termios *)attrs[fd]); \ } EOF # If this is TUI app, let it redraw. kill -WINCH "$pid" tail -f /dev/null --pid "$pid" やっていることは基本的に単純で,gdb でプロセスを attach して file descriptor の 0 から 2 までを書き換えています。compile ってのは gdb のコマンドで,渡したコード をコンパイルして,そのプロセスで実行してくれる。このときに

awkなしでフィールドを切り出す

スペース区切りの出力から特定のフィールドを取り出す方法といったらだいたい cut か awk ってことになると思うんですが,フィールドを取り出すためだけに awk を起動するのもなー と思う。で,cut を使おうとするが,これが空白の連続に対応できない。 よくあるプログラミング言語の split 関数みたいな感じだなと。 で結論から言うとっていうか結論を言ったらこの投稿は終了なんだけど,以下のようにする。 $ your-command | tr -s ' ' | cut -d ' ' -f2 これでも先頭に空白がある ps の出力とかは謎の 2-index みたいになってしまうけど まあ妥協。変えたかったら sed とかで頑張ればいいと思うけどそこまでやる価値があるのかは不明。 あとオプションと引数をつなげると文字数減らせるハックな

GNOME 端末 と Sixel

GNOME 端末,というか GNOME 端末が使っている vte に Sixel が入ってほしいな, と思っていたけど,これ を見た感じ入る日は来なさそうだな,と思った。 この issue は重複する issue を上げるな,というところから, sixel のプロトコルがレガシーでパレットベースで,view/model を分けるのが困難 という説明までしている。 bugzilla の方もパッチはあるけどそのパッチが入る雰囲気はゼロだった。

ls --hyperlink の Feature Request を見つけた

https://lists.gnu.org/archive/html/coreutils/2017-05/msg00000.html こんな変なものも割と簡単に受け入れられるんだな,と思った。 で,ここにパッチとかも入ってるメール。 https://lists.gnu.org/archive/html/coreutils/2017-08/msg00038.html

xterm でクリックできるっていうのでいうと

xterm だと何らかのコントロールシーケンスでマウスのクリックを 取れるとかいうのがあったな。そんなコントロールシーケンス使ったことないので 説明はできないが。 working example でいうと,w3m とか。w3m 素敵だよね。 こんにちの Web には対応不可能感が漂いすぎてるけど。 あと Emacs だと M-x xterm-mouse-mode でマウスで カーソルを動かしたりできるようになる。

ハイパーリンクのエスケープシーケンス

端末エミュレータで URL に飛ぶといえば,たいていのものについている URL の自動検出機能 を使うというのがまあ普通の答えになる気がするんですが,任意のテキストに URL を割り当てる エスケープシーケンスというのが世の中には存在するという話。(今日知った) TL;DR ハイパーリンクは次のようなエスケープシーケンスで実現できる。1 "\e]8;;${URL}\a${LABEL}\e]8;;\a" 例えば,http://example.com に飛ぶ 「Click here」というリンクを作りたかったら, 下のようにする。 "\e]8;;http://example.com/\aClick here\e]8;;\a" 経緯 これを知ったきっかけというのは, $ coredumpctl --help というコマンドを実行したことだった。ヘルプの下の方に coredumpctl(1) man page という点線のついた文字が表示されていて,右クリックのメニューからリンクをたどっ

すごい syslog の話

なんか /var/log あたりを見ても syslog がないな,と思っていたら, systemd がすごい syslogd をやってるらしい。systemd 肥大化しすぎでは……。 で,そのログを見るには, $ journalctl とかする。 でも,これは保存されているログが古い方から全部出てしまうのでたいていの場合は用途に合わない気がする。 僕の場合は 12 月のログとかが最初に出てきてうーん,となった。 たいていの場合はログは新しい方から見たいんではないかと思うので,そういう場合は, $ journalctl --reverse とかすると,新しいものから表示してくれる。 あと --grep オプションとかもあって, $ cat /var/log/syslog | grep foobar みたいにやってたところを 1 つのコマンドで済ませられるっぽい。うーん,でもこれはなんかなー。 他には --since とか --until とかもあるっぽ

Unicodeの正規化と濁点

Unicode において,濁音の表現方法は2つあります.一つが濁点のついた文字のコードを使用する方法です. もう一つが濁点のついていない文字と濁点を組み合わせる方法です. 後者の方法だと,本来は濁点のついていない文字に濁点をつけることができるのでおもしろかったりします. uconv コマンドを使うとこれを相互に変換できます. uconv は (Debian 系のディストロでは) icu-devtools パッケージの一部として APT で入れられます. 以下が 2番目の表現方法から 1 番目の表現方法に変換する例です. $ echo -n が | uconv -x NFD が 分解されたものを再度合わせるのは以下です. $ echo -n が |n uconv -x NFC が と例をあげましたが,たいていの環境ではその違いを目視で確認できないと思います. xxd を使いましょう

ImageMagick の処理を高速化する

数日前からシェル芸で画像を出力するのが楽しくて毎日のようにやっているのだが、画像の処理は思った以上に重く、よくタイムアウトする。 しかも強引なやり方をしているのでとてつもない長さのワンライナーが完成してウンザリな感じになる。 mpr: mpr: は ImageMagick 出力を一時的にメモリに置いておけるっぽい。一回一回ファイルに結果を書き出したり、パイプで ImageMagick をつなげたりせずに出力結果を利用することができるので、起動のオーバーヘッドやファイル I/O のオーバーヘッドを軽減できる。 これはファイルとして使える (ファイルみたいに入力や出力に使える。) +delete これまでの引数をなかったことにする。このとき、 mpr: などの中身は消えない。 ジェネレート系 xc:[色]