悩み
- 最初は全部関数として~/.bashrcに書いていた。
- ~/.bashrcが長大化しすぎたので分割したりした。
- それでも長くなったので実行可能ファイルにしてパスを通したディレクトリに置いたりした。
- あれ、どっちがいいんだろう……
ログイン時の読み込み時間
- ログイン時には毎回~/.bashrcが読み込まれる。
- 読み込むものが多いと当然時間がかかる。
- 実行可能ファイルにしておけば、実行時にパスが通ったところから該当するファイルを探すだけ。
- 長大なスクリプトは、基本的に実行可能ファイルにすべき。
関数でないとできないこと
現在のシェルに影響を及ぼす
- 例えば以下のようなコマンド。
cd ~/Documents # ディレクトリを移動
source ~/.bashrc # 設定ファイルを再読み込み
- これらのコマンドを実行可能ファイル内に記述しても、現在のシェルには反映されない。
- 実行可能ファイルだと、別プロセスで実行されるため。
現在のシェルを参照する
- 例えば以下のようなコマンド。
history 2 | head -n 1
- 関数として実行しなければ、現在のシェルの情報を参照できない。
コマンドを群として管理
- 関連する小さなスクリプトを大量に書く必要がある場合、関数の方が書くのも管理も楽。
- 用途ごとに定義ファイルを分けることも可能。
- 定義ファイルを手動で
source
することで、任意に有効化することも可能。
- 定義ファイルを手動で
実行可能ファイルでないとできないこと
特定のディレクトリでのみ有効なコマンド
- 環境変数PATHに相対パスを追加することで実現できる。
#~/.bash_profile
export PATH="$PATH:./bin"
- 上記のように設定した場合、カレントディレクトリ内のbinディレクトリにパスが通り、その中のスクリプトが実行できる。
-
./bin/hoge
があれば、hoge
で実行。
-
- でも、そういうところでこそcdしたくない?
スクリプトの編集を即時に反映する
- 関数だと
source
しなければ変更が反映されないが、ファイルなら保存するだけ。
xargs
で引数を得る
- 関数でできなくもないが大変。
そうは言ってもファイルを作るのがめどい
- 実行可能ファイルを作るスクリプトを作っておくべき。
- 指定ディレクトリにデプロイとか、
- 実行権限を付けるとか、
- shebangを入れるとか、
- これには入れてないけどパスの通ったディレクトリにシンボリックリンクするとか、
- 自動化してしまえば思いついたときすぐ作れる。
#!/bin/bash
SHEBANG="#!/bin/bash"
DIRPATH=~/bin
usage () {
echo "Usage: $0 [-i] [language] [-lh]"
}
while getopts li:h OPT
do
case $OPT in
l)
DIRPATH="$(pwd)/bin"
mkdir -p "$DIRPATH" >& /dev/null
;;
i)
case "$OPTARG" in
osa*|ap*)
SHEBANG="#!/usr/bin/osascript"
;;
ru*)
SHEBANG="#!/usr/bin/ruby"
;;
*)
echo "$OPTARG is undifined language" 1>&2
exit 1
esac
;;
h)
usage
exit 0
;;
?)
usage
exit 1
;;
esac
done
shift $((OPTIND - 1))
if [ -n "$1" ];then
NAME="$1"
else
echo "Input script NAME/path" 1>&2
read NAME
if [ -z "$NAME" ]; then
echo "No NAME" 1>&2
exit 1
fi
fi
FILEPATH="$DIRPATH/$NAME"
if [ -f "$FILEPATH" ];then
echo "Same file is existing" 1>&2
exit 1
fi
if [ ! -d "$(dirNAME "$FILEPATH")" ]; then
mkdir -p "$(dirNAME "$FILEPATH")"
fi
touch "$FILEPATH" && chmod +x "$FILEPATH" && ( echo "$SHEBANG"; echo "" ) > "$FILEPATH"
mvim +2 "$FILEPATH"