bash」タグアーカイブ

macOS sh

macOS で man sh を初めて見てみたんだけど。

つまり /bin/sh は /private/var/select/sh を起動する。
その /private/var/select/sh は /bin/bash へのシンボリックリンク。

つまり macOS の sh も bash が本体ということみたい。
環境によってリンク先は変わるかもだが筆者の Air はこうなっていた。
なんでこんな面倒な仕組みになっているんじゃい。
Fedora みたいに直接 sh というリンクにすればいいのに。

でもまてよ、sh と bash は動作が違っていたよな。
(bash|zsh) read command 2 | PaePoi

色々探してみたらこんなのを見つけた。
/bin/sh と /bin/bash の違い – 双六工場日誌

あぁそういうことだったんだ。
Fedora 30 で試したらやはり posix のオプションが違っていたよ。
sh は bash を posix sh 互換で起動する呼び出し方で合っているかな。
でも Fedora の sh は \n 文字を文字として扱うのよね、まあいいか。

しかし何故 dash も選択肢に入っているのか?
Debian Almquist shell – Wikipedia
debian 系のコレと同じものだと思うけど、標準で入っている理由がワカンネ。

macOS 10.15 Catalina

macOS 10.15 Catalina を導入しました。
Macbook Air 2018 の Mojave からのアップグレードです。
さて、一番気になる所をチェック。

デフォルトシェルは初期状態では bash のまま。
ただし [zsh に自分で変更しろ] というメッセージが毎回出る。
.bashrc でカスタムしていた所は .zshenv に変換コピペ等の猶予がある。
一通り調べた後で筆者も zsh に変更します。

Python2 も実は残っている、同様なメッセージが出る。
でも Python3 ってあれ?

筆者は自分で Python3 を入れたけど、それは /usr/local/bin にある。
デフォルトで /usr/bin に入るようになったみたい、情報が無かったけど。
シンボリックリンク先は同じなので残しても問題ないけど local のは消すかな。

PyObjC は pip3 で自分で入れたのだけどコレも最初からあるのかいな?
他人の情報を待とう。

筆者自作の Comipoli はソースもビルド済みも問題なく動いた。
ただソースのまま起動するのが異様に遅くなったような気が。
macOS アプリケーション

何より気になる JXA での NSRect のバグ。

そのまんまヤン!
もう JXA はダメだ、GUI は PyObjC に完全移行しよう。

httpd.conf はやはりリセットされた。
変更点は特に無いようだ、とっとと元に戻す。
macOS httpd.conf | PaePoi
んで

sudo apachectl restart

そんなことより。
sips を使ったスクリーンショットの 72dpi 変換ができない!
macOS をクイックアクションで拡張 – L’Isola di Niente
シェル変更の影響か?

#!/usr/bin/env python3

# change72dpi *.png

import sys, os
from AppKit import *
from Quartz.CoreGraphics import *

args = sys.argv[1:]

for s in args:
    name = os.path.basename(s)
    src_image = NSImage.alloc().initWithContentsOfFile_(name)
    img = NSBitmapImageRep.imageRepWithData_(src_image.TIFFRepresentation()).CGImage()
    h = CGImageGetHeight(img) // 2
    w = CGImageGetWidth(img) // 2
    ctx = CGBitmapContextCreate(None, w, h, 8, 4 * w, CGColorSpaceCreateDeviceRGB(), kCGImageAlphaPremultipliedLast)
    CGContextDrawImage(ctx, CGRectMake(0, 0, w, h), img)
    imgref = CGBitmapContextCreateImage(ctx)
    out_image = NSImage.alloc().initWithCGImage_size_(imgref, (w, h))
    bmp = NSBitmapImageRep.imageRepWithData_(out_image.TIFFRepresentation())
    data = bmp.representationUsingType_properties_(NSBitmapImageFileTypePNG, {})
    data.writeToFile_atomically_(f'72dpi-{name}', True)

以前書いた使い捨てスクリプトでなんとか 72dpi 変換した。
しかし端末でこんなの出ていたっけ?

とりあえず気がついたのはそんなところ。
相変わらず mac らしい使い方をしていないなぁ。

(bash|zsh) array and for

zsh の for は何か bash と違うと思ったら
どうやら zsh では isf 区切りではなく配列を使うようだ。
先に配列について調べておく必要があるな。

zsh の配列操作の基本から応用まで – Qiita

配列は [1] から始まるんかい。
lua なんかもそうだけど何故ゼロにしなかったのか。
bash と整合性が、、、、、
って bash では isf 区切りが基本すぎて誰も使っていないと思うけーが。

シェルスクリプトの文字列と配列 – L’Isola di Niente

コイツを zsh 向けに書き換えしてみよう。

#!/bin/zsh

# 配列の作成、括弧で囲む
array=(先頭 次の項目 最後)

# echo してみる、インデックス指定無しだと先頭が出力される
echo $array
#=> 先頭

# インデックスは C 言語と同様
# bash と違って中括弧不要
# 先頭は 1 で最後は -1
#echo ${array[1]}
echo $array[2]
#=> 次の項目

# += で追加できる
# bash と違い括弧で囲む必要はない
#array+=(追加)
array+=追加
# 全てを出力する時は @ を指定
echo $array[@]
#=> 先頭 次の項目 最後 追加

# インデックスを使って追加や書き換えできる
# bash と同じだけどインデックスに注意
array[3]=三番目
echo $array[@]
#=> 先頭 次の項目 三番目 追加

# 範囲は関係ない、インデックスは並び順ではなく番号
array[10]=九番目
echo $array[10]
#=> 九番目

# 単なる未定義になる
echo 百番目は $array[100] です
#=> 百番目は です

# ポインタではない
array[-2]=$array[1]
array[1]=最初
echo $array[-2]
#=> 先頭

# bash で全てを出力する時は @ を指定
# for item in "${array[@]}"; do
for item in $array; do
    echo "item: $item"
done
# bash と同じヒアドキュメントで無理やり複数業コメントが可能
# atom, vscode 等は色分けしてくれる
: << __OUTPUT__
item: 最初
item: 次の項目
item: 三番目
item: 追加
item: 先頭
item: 九番目
__OUTPUT__

# こんな初期化もでき...なかった
#new_array=([1]=456 [2]=789 [0]=123)
#echo $new_array[@]
#=> error

なるほど、bash よりは簡単に使えるようにっているんだね。
Python 等が解る人ならインデックスにさえ注意すれば普通に扱える。
もっと機能はあるけど push(append) と for を覚えれば大抵困らない。
で、for はやはり配列を回すということみたい。

#!/bin/zsh

# 以下は共通です
# *.sh 等のワイルドカードも使えます
for f in これは 共通 です; do
    echo $f
done

# 変数に入れる場合 zsh は配列にする
# ワイルドカードなら arr=(*.sh), isf=*.sh
# てか zsh は arr=*.sh としてもワイルドカードを展開しない
if [[ $ZSH_EVAL_CONTEXT = toplevel ]]; then
    arr=(zshは 配列に します)
    for s in $arr; do
        echo $s
    done
    # 省略構文、変数が配列でも括弧が必要
    #for a ($arr) echo $a
else
    isf='bashはご存知 isf 区切りです'
    for s in $isf; do
        echo $s
    done
fi

# zsh の省略文
# do done の代わりにブレースを使うこともできる

# ブレース展開の結果が異なる
echo {02..10}
# bash: 2 3 4 5 6 7 8 9 10
# zsh:  02 03 04 05 06 07 08 09 10

ワイルドカード展開も配列になるのかなと思ったけど違うようだ。
bash と違ってイコール直後のアスタリスクは只の文字列扱いになるし。
in 直後の isf 区切りのみ特別扱いってことなのかな?
実際それで実用上は問題は無い気もする。

zshのfor文は強かった – Qiita

すごく機能は豊富だけど覚える必要があるかどうかは微妙。

それより発見、ブレース展開が小細工せずにゼロ詰めできる!
これだけのために Fedora にも zsh を入れようかと思うくらい便利。
って、ここ何のブログだっけ?

(bash|zsh) read command 2

read コマンドをもう少し。
ファイルの読み込みなんかは bash と同じみたい。

bash: ‘\n’ in read file (part2) | PaePoi

while read -r line; do
    echo $line
done << __DOC__
aaa bbb
ccc\nddd
eee
__DOC__

うん、sh と同じく \n 文字は改行扱いになるってか。
それより、ついでと思い bash 直指定したら文字列扱いになってしまったんだけど。
Fedora では sh は単なる bash へのシンボリックリンクなんだけど。

macOS の sh は別コマンドなのか、でも [[ とかの bash 拡張は使えるし。
正直よくわからんぞ。
シバンは明確に #!/bin/bash とかを利用したほうが良さげ。

(bash|zsh) read command

zsh と bash の read コマンドは全然違うようだ。
bash, zshでyes/no判定をするワンライナー – Qiita

公式のビルトインコマンド man ページも見つけた。
zsh: 17 Shell Builtin Commands

早速試そうと思ったけど bash とソースを分けるのは色々と不便だ。
zsh にしても $SHELL は bash のままだし、readonly に何か無いかな?

あった、$ZSH_EVAL_CONTEXT が定義されているかで判別できそう。
プロンプトとライン入出力と Y|N 判定をひとまとめに書いてみた。

#!/bin/zsh

echo 'May I ask your name?'

if [[ $ZSH_EVAL_CONTEXT = toplevel ]]; then
    read name\?'> '
    echo "Hello $name san"
    printf 'Do you like zsh? (y|N): '
    read -q && echo '\nGreat!' || echo '\noh my god...'
else
    read -p '> ' name
    echo "Hello $name san!"
    read -n1 -p 'Do you like bash? (y|N): ' res
    [[ $res = [Yy] ]] && printf '\nGreat!\n' || printf '\noh my god...\n'
fi

マジで全然ちげえ、この手段でまとめページを作るのは無理があるみたい。
zsh の read -q でプロンプトは出せないのかな?

おまけで、zsh の echo はエスケープシーケンスが使えると解った。
macOS の bash は echo -e すら使えないのに。
組み込みコマンドは大体別物と思ったほうが良さげ。

Atom の script は bash|zsh のシバンも見分けしてくれる、助かる。
入力はできないけど、まあそれは Gedit も同じだ。