Shell scriptで色々実行しようとしていると、余計な拡張の入ったshellは使いたくなくなる。拡張に依存してPOSIXを忘れてしまうと、マシンごとに異なるshell環境でどハマりをしてしまうからである。
というわけで、POSIX準拠の比較的Primitiveなshellを探し求めてきたわけだが、結局選択できるshellは3種類に絞られてしまった。 ; ash : NetBSDやFreeBSD に付属するshell で、Almquist shellを元にしたもの ;dash : Debian, Ubuntuで採用されているshellで、Almquist shellをdebian Projectで改変したもの ; yash : magicant(WATANABE Yuki)氏が開発したYet Another SHell。一部制限事項を除きPOSIX.1-2008 (IEEE Std 1003.1, 2016 Edition) を全てサポートしているshellで、日本語の情報も十分に提供されている。
しかも、ashとdashは同じものからの派生なので、実質はそれほど変わらない。
自分の場合、OS-X上で開発しているから、/bin/shはdashのようだが、これはcommand-line edit機能をオフにしてコンパイルされているから、login-shellで使うには自力compileするか、HomeBrewで導入する必要がある。
色々探してて、yashがかなり良さそうなので試してみた。
本記事では、この yash をMacOS-X BigSur上のtmuxで利用するためのDraftである。もう少し書きたいことはあるので、何回かに分けて書いた上でまとめたいという野望はある。
yashの情報は以下を参照のこと
特徴は以下の通り
yashの環境としては、
という2つの条件を満たすように設定する。
login時に読み込まれるファイル。システムの標準設定を記載する。
yashは、特に指定をしない限り、/etc/profile
や~/.profile
を読み込まない。代わりに、~/.yash_profile
を読み込む。
個人的にはこの挙動は気に入らないので、ln -s ~/.profile ~/.yash_profile
して共通にしている。
################################################################################ # Shell Configuration ################################################################################ ## Environment Variables # UNIX Standard Paths PATH='/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/local/sbin' # System Specific Paths [ -d "/usr/local/opt/openssl/bin" ] && export PATH="/usr/local/opt/openssl/bin:${PATH}" # Personal Paths [ -d "${HOME}/bin" ] && export PATH="${PATH}:${HOME}/bin"
ここでは、login時にどうしても設定しなければならない最小限の環境変数を設定する。こうすることで、shell scriptを実行する際に怪しい挙動を考えなくて良くなる。
.yashrcは、shellがInteractiveモードで起動された場合に実行される(読み込まれる)ファイル。ここに、生活に関係する大量の設定を投入する。
注意点として
ln -s ~/.login ~/.yashrc
を実行して、全てのshellで共通にするなどが挙げられる。
################################################################################ # Shell Configuration ################################################################################ ### Functions ## Common hup() { (read pid; kill -HUP $pid) </var/run/$1.pid; } start_tmux() { __TMUX_BIN__=`which tmux` [ ! -x ${__TMUX_BIN__:-""} ] && echo "RET" && unset __TMUX_BIN__ && return __TMUX_SESS__=`hostname` __TMUX_SESS__="${__TMUX_SESS__%%.*}" [ ! -z ${__TMUX_SESS__:-""} ] && __TMUX_SESS__="${__TMUX_SESS__}" if [ -z ${TMUX:-""} -a -z ${STY:-""} ]; then __TMUX_OPTION__="" if ${__TMUX_BIN__} has-session -t ${__TMUX_SESS__} > /dev/null 2>&1 ; then __TMUX_OPTION__="attach -t ${__TMUX_SESS__}" else __TMUX_OPTION__="new-session -s ${__TMUX_SESS__} ; split-window -h" fi ${__TMUX_BIN__} ${__TMUX_OPTION__} fi unset __TMUX_BIN__ __TMUX_SESS__ __TMUX_OPTION__ } ## for yash if [ -x /usr/local/bin/yash ]; then sh() { yash --posix "$@"; } else sh() { /bin/sh "$@"; } fi ## Yash common configuration if [ ! -z "${YASH_VERSION}" ] ; then # set -f # -f すると'*'が展開されなくなる bindkey --emacs '\^L' clear-and-redraw-all # for emacs mode # POSIX collect modeでは、YASH拡張が使えなくなる # set -o posixlycorrect fi ### Personal Environment Variables # for HomeBrew export HOMEBREW_GITHUB_API_TOKEN="37edea7e3d75b4a84fb2d913008af7ebef407033" # Shell Variables. umask 022 ## Environment Variables EDITOR=vi for i in lv less more; do which $i 2>&1 > /dev/null && PAGER=`which $i`; done; ## Aliases alias h='fc -l' alias j=jobs alias ll='ls -laFo' alias l='ls -l' alias g='egrep -i' alias man="LANG=C /usr/bin/man" alias nossh='ssh -o "UserKnownHostsFile /dev/null"' alias noscp='scp -o "UserKnownHostsFile /dev/null"' alias svn='LANG=ja_JP.UTF-8 svn' ## Shell command line editing ***WARN*** set -o emacs ( set -o tabcomplete 2>/dev/null ) && set -o tabcomplete # for NetBSD /bin/sh : ${__HOSTNAME__:=$(uname -n)} PS1="${__HOSTNAME__%%.*}" case `id -u` in 0) PS1="${PS1}# ";; *) PS1="${PS1}$ ";; esac unset __HOSTNAME__ ## Execute command [ -x /usr/bin/tset ] && eval $(tset -sQrm 'unknown:?unknown') [ -f $HOME/bin/goenv.sh ] && . $HOME/bin/goenv.sh [ -f $HOME/bin/rbenv.sh ] && . $HOME/bin/rbenv.sh start_tmux ################################################################################ # # 予約環境変数 # i : for counter # __HOSTNAME__ : hostname # # __TMUX_BIN__ : tmux executable file # __TMUX_OPTION__ : tmux options # __TMUX_SESS_NAME__ : tmux session name # # __PAGER__ : temporaly pager commands # # This .profile is checked under following OSs. # - MacOS-X BigSur # # This .profile is checked under following shells. # - zsh (5.8) # - yash (2.51) # - dash (from HomeBrew) # - ash (FreeBSD-12.2-p3) # # ***** WARNINGS ***** # - dash included in OS-X BigSur is compiled without commandline completion. Must use HomeBrew version.
これで、個人的に必要になる設定は終わり。
注意点は、start_tmux()。
start_tmux() { __TMUX_BIN__=`which tmux` [ ! -x ${__TMUX_BIN__:-""} ] && echo "RET" && unset __TMUX_BIN__ && return __TMUX_SESS__=`hostname` __TMUX_SESS__="${__TMUX_SESS__%%.*}" [ ! -z ${__TMUX_SESS__:-""} ] && __TMUX_SESS__="${__TMUX_SESS__}" if [ -z ${TMUX:-""} -a -z ${STY:-""} ]; then __TMUX_OPTION__="" if ${__TMUX_BIN__} has-session -t ${__TMUX_SESS__} > /dev/null 2>&1 ; then __TMUX_OPTION__="attach -t ${__TMUX_SESS__}" else __TMUX_OPTION__="new-session -s ${__TMUX_SESS__} ; split-window -h" fi ${__TMUX_BIN__} ${__TMUX_OPTION__} fi unset __TMUX_BIN__ __TMUX_SESS__ __TMUX_OPTION__ }
set -o
set -o poisly-correct
local
typeset -f
まだまだ書くべきことはたくさんあるが、ひとまずここまで。