転載・引用について

ユーザ用ツール

サイト用ツール


tweet:2021:0317_01

yash

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の情報は以下を参照のこと

特徴は以下の通り

  • 小さい
  • POSIX.1-2008準拠
  • コマンドライン補完やコマンドラインエディット機能を持つ
  • LicenseはGPL… → 個人的には、ここだけ気に入らない。BSDライセンスなら…とも思うが、まぁ、仕方がない。
  • Software Development Utilities オプションと C-Language Development Utilities オプションを備えた任意の POSIX.1-2001 環境でビルド・実行できる
  • MacにはHomeBrewからInstallできる

yashの設定

yashの環境としては、

  1. login shellとしては拡張の機能を使いたい
  2. shell scriptを実行する環境としては、POSIX shellとして動いて欲しい

という2つの条件を満たすように設定する。

.yash_profile

login時に読み込まれるファイル。システムの標準設定を記載する。

yashは、特に指定をしない限り、/etc/profile~/.profile読み込まない。代わりに、~/.yash_profileを読み込む。

個人的にはこの挙動は気に入らないので、ln -s ~/.profile ~/.yash_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を実行する際に怪しい挙動を考えなくて良くなる。

  • /usr/local/opt/openssl/bin は、MacOS BigSurにおいて最新版のopensslをコマンドラインから実行するためにこのように設定している。
  • /sbin,/usr/sbin,/usr/local/sbin をPATHに入れずに、コマンド起動時に手入力する人もいるが、私は面倒なので、PATHに入れている。
  • ~/bin は人によって色々な異論があると思うが、個人的にはscriptが大量にある関係もあって、PATHに加えている。

.yashrc

.yashrcは、shellがInteractiveモードで起動された場合に実行される(読み込まれる)ファイル。ここに、生活に関係する大量の設定を投入する。

注意点として

  • .yashrc は ln -s ~/.login ~/.yashrcを実行して、全てのshellで共通にする
  • yash/ash/dash/bash/zsh 固有の設定はshellの種類を判別して記述する
  • yashにおいては、.yash_profileを読み込んだのち、(POSIX非互換モードの場合、)/usr/local/share/yash/initialization配下にあるファイル(特にcommon)を読み込む。その際にPS1を書き換えてしまうので、.yash_profileにPS1など幾つかの設定を記述しても無駄になる。
  • 迂闊な設定ミスをすると、Command-line completionやEditor利用中のCtrl-Zが効かなくなるなどの怪しい挙動を示すので注意が必要

などが挙げられる。

.yashrc
################################################################################
# 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
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__
}
  • tmuxは、複数を重なって起動すると幸せにならないので、Hostnameなどを利用したtmux sessionを作成し、必要があればnew-session、なければ attach、それもなければ、tmuxをskipするようにしてある
  • 一時利用した環境変数はちゃんと消去する
  • どこかで間違って上書きされないように、被らない変数名をつけ、確実にunsetする
  • localはPOSIXに存在しないので、利用しない

yashのDebugのために必要な幾つかのコマンド

  • set -o
    • 現在の各種オプションの設定確認
  • set -o poisly-correct
    • POSIX互換モードに移行する
  • set -o emacs
    • emacsモードでの行編集が可能になる
  • local
    • local変数を表示する
  • typeset -f
    • 定義されている関数を表示する

終わりに

まだまだ書くべきことはたくさんあるが、ひとまずここまで。

このウェブサイトはクッキーを使用しています。 Webサイトを使用することで、あなたはあなたのコンピュータにクッキーを保存することに同意します。 また、あなたはあなたが私たちのプライバシーポリシーを読んで理解したことを認めます。 同意しない場合はウェブサイトを離れてください。クッキーに関する詳細情報
tweet/2021/0317_01.txt · 最終更新: 2021/05/19 18:55 by 127.0.0.1

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki