Software_SHELL

SHELL

┌──┐
│目次│
├──┘
☆BASH bash
◆特殊ファイル spe
◆キー入力、行編集 key
◆特殊文字、クォーティング、コマンド構文 com
◆組み込みコマンド emb
◆ジョブ制御 job
◆変数 var
◆TIPS tips
◆環境変数 embv
◆例 sample
☆C shell csh
◆環境変数の設定 cembv


☆BASH


◆特殊ファイル

①/etc/profile
│ ログイン時に自動実行
②$HOME/.bash_profile
もしくは
$HOME/.bash_login
$HOME/.profile
│ ログイン時に自動実行
③$HOME/.bashrc
│ シェル起動時に自動実行
④$HOME/.bash_logout
│ ログアウト時に自動実行
⑤$HOME/.bash_history
│ 前のセッションのコマンドの記録
⑥$HOME/.inputrc
│ GNU readlineライブラリの設定ファイル
⑦/etc/passwd
│ ユーザー名補完等で使用
⑧/etc/hosts
│ ホスト名補完等で使用

_◇設定ファイルの読み込み手順

ログインでなければ
│ ①/etc/bash.bashrcの読み込み
│ ②$HOME/.bashrcの読み込み

ログインであれば
│ ①/etc/profileの読み込み
│ ②$HOME/.bash_profileが存在すればそれを読んで完了
│ ③②が無ければ$HOME/.bash_loginを読み込もうとする
│ ④③も無ければ$HOME/.profileを読み込む。
│ ⇒Ubuntuは.profile


◆キー入力、行編集
①[tab]キー
先頭数文字入力し、その後tabを押すことで、PATHに指定されたディレクトリからファイル名を検索する。
※前方一致。該当するものが複数ある場合はエラーとなるので、判断がつくところまで入力する必要がある。

②^a
│ 行頭
③^e
│ 行末

④←(^b),→(^f)

⑤ESC t
│ 直前の引数2個の順序の変更
⑥^d 一文字消去
⑦^k 右側消去
⑧^l 画面クリア
⑨^x 取消

※vi風キー操作の設定
│ set -o vi

※コマンドヒストリ
①history
│ 一覧の表示

②! n
│ 履歴番号nを再実行

③↑(^p),↓(^n)
│ コマンドヒストリ、シリアルに移動

④^r
│ コマンドヒストリの検索


◆特殊文字、クォーティング、コマンド構文

⑦*?[]~!
⑧”‘\

⑨`
“で囲まれた外部コマンドの実行結果を変数の値として取り込む
例)
num=`wc -l Fname | cut -d’ ‘ -f1`
例)
i=`expr $i + 1`

⑩$()
│ 外部コマンドの実行結果を変数の値として取り込む
例)
│ pid=$(cat /var/run/toy.pid)
※toy.pidというファイルの内容が変数pidに格納される。

⑪改行,空白,タブ

⑫#
│ コメント。#から行末まで。

⑬” ”
│ 囲んだ部分を1つのコマンドライン引数にまとめる

⑭’ ‘

⑮\
│ コマンド先頭に付加することでエイリアス変換しない

_◇コマンドセパレータ
;
│ コマンドセパレータ。複数のコマンドを順次実行する。
│ 例)
│ cmd1; cmd2

_◇バックグラウンド実行
&
│ 例)
│ cmd &

_◇AND実行、OR実行
正常終了した場合のみ次コマンド実行
│ 例)
│ cmd1 && cmd2

正常終了しなかった場合のみ実行
│ 例)
│ cmd1 || cmd2

_◇サブシェル
()
│ コマンドグループとして実行。
│ 例)
│ (cmd1; cmd2)

_◇コマンドブロック
{}
│ 現在のシェル内でコマンド実行。
│ 例)
│ {cmd1; cmd2}

_◇パイプ
|
│ 前のコマンドの出力を次のコマンドへ。
│ 例)
│ cmd1 | cmd2

_◇リダイレクト
><&

※ファイル記述子
0 stdin
1 stdout
2 stderr

例)
>file
│ 標準出力をfileに書き込む。
<file
│ fileを標準出力として読む。
>>file
│ fileに追記
2>file
│ stderrをfileに書き込む
2>>file
│ stderrをfileに追記
>file 2>&1
│ stdoutとstderrをfileに書き込み
>>file 2>&1
│ stdoutとstderrをfileに追記

<>file

<<text

n>file

n<file

>&n

<&n

&>file

<&-

>&-

n>&-

n<&-

_◇ファイル名展開用メタ文字

※ファイル名展開機能(グロブ)はシェルの機能である。
<>Windowsではプログラム側の機能である
※グロブを働かせたくない場合は””で囲む

※シェルのメタキャラクタ
①*
空文字列を含む任意の文字列に一致

②?
任意の1文字に一致

③[abc…]
括弧内の任意の一文字に一致。「-」による範囲指定可。

④[!abc…]
括弧内の任意の一文字を含まない文字に一致

⑤~username
│ ユーザのホームディレクトリ
⑥~+
│ 現在の作業ディレクトリ
⑦~-
│ 直前の作業ディレクトリ
⑧|
│ パターンをorで区切って並べることができる。

例)
│ ls new*
│ cat ch?
│ vi [D-R]*

※POSIXブラケット
[]内で使用する
例)
[[:alpha:]]

[:digit:] 数字
[:alpha:] アルファベット
[:alnum:] アルファベットと数字
[:upper:] 大文字
[:lower:] 小文字
[:xdigit:] 16進数構成文字
[:cntrl:] 制御文字
[:blank:] スペースとタブ
[:space:] スペースとタブと改行
[:graph:] スペース改行のぞく表示文字
[:print:] スペースを含む表示文字
[:punct:] カンマやピリオド


◆組み込みコマンド

_◇コメント
#
│ 同じ行の後につづく文字列を無視

#!cmd
│ スクリプトの最初の行で用いられた場合、指定されたcmdを起動する

_◇空コマンド
:

終了ステータス0を返す

_◇sourceコマンド
source ファイル
│ 指定したファイル(実行可能でなくてもよい)を読み込んで解釈実行する。
│ /を含まなければPATHを検索してファイルを見つける。

. ファイル
│ sourceと同じ

_◇alias

書式)
alias
│ 定義された全ての別名を表示する
alias name=’cmd’
│ コマンドcmdの省略形としてnameという別名を与える。
│ ⇒引数をとる場合は function で定義

_◇ファイル関係のテスト

※ファイルが存在する場合に実行
│ test -e ファイル名 && 実行内容

※ファイルが存在しない場合に実行
│ test -e ファイル名 || 実行内容

※ディレクトリなら実行
│ test -d ディレクトリ名 && 実行内容

_◇条件判断 if

if [ 条件部 ]; then
    条件成立の場合の実行内容
elif [ 条件部 ]; then
    条件成立の場合の実行内容
else
    条件不成立の実行内容
fi

※本来 if と then は別行でなければならない。しかし、条件式の後に「;」をつけることで1行にかける。

※if はその後のコマンドの終了ステータスが0なら真とみなす

※条件式は通常 test コマンドで評価するが、代わりに
[ ]
の中に書いてもよい。
最初の「[」はコマンド名であり、後の「]」はその引数の末尾。
よって「[」の後と「]」の前に必ずスペースを必要とする

※文字列比較
=
!=

例)

#!/bin/sh
val="YES"
if [ "$val" = "YES" ]; then
    echo "YES"
else
    echo "NO"
fi

例)
引数が3個でなければ

if [ $# -ne 3 ]; then
    ...引数足らない
    exit 1
fi

例)
第1引数で与えられる名のファイルが存在しなければ

if ! [ -e $1 ]; then
    ...ファイルがない
    exit 1
fi

※引数の数
($#)

※数値比較
-eq equal
-ne not equal
-lt less than
-le less than or equal
-gt greater than
-ge greater than or equal

※論理演算
-o OR
-a AND

_◇case 選択

    case $変数名 in
    パターン1)
    パターン1のときの実行内容
    ;;
    パターン2)
    パターン2のときの実行内容
    ;;
    *)
    どれでもないときの実行内容
    esac

※文字列がパターンに一致するならば;;までのコマンドを実行する

※パターンは | で区切って複数ならべることができ、そのうち一つが一致すればよい

例)

#!/bin/sh
val="YES"
case "$val" in
    YES|yes)
        echo "YES."
        ;;
    *)
        echo "NO."
        ;;
esac

_◇for ループ

書式)
for 変数名 in リスト;
do 実行内容;
done

例)

#!/bin/sh
for i in 1 2 3 ; do
    echo "i=$i"
done

※スクリプト引数毎処理
⇒for文のin以降を省略すると、スクリプトの引数である定位置パラメータが対象となる
例)

#!/bin/sh
for i ; do
    echo "i=$i"
done

※ワイルドカード展開
⇒文字列に*や?などのワイルドカード文字が含まれる時、該当するファイル名があればファイル名に置き換えられる。該当ファイルがなければ、ワイルドカードを含む文字列そのままが渡される

#!/bin/sh
for i in *.sh *.SH ; do
    echo "i=$i"
done

_◇while/until ループ

while [ 条件コマンド ] ; do
    [コマンド]
done

⇒条件コマンドの戻り値が0の間コマンドを繰り返す。0以外で繰り返し終了

until [ 条件コマンド ] ; do
    [コマンド]
done

⇒条件コマンドの戻り値が0以外の間コマンドを繰り返す。0で繰り返し終了

_◇スクリプト終了
│ exit 終了番号
│ ※終了番号は省略可だが、成功で0、それ以外は1以上が一般的。

⑥エイリアス
│ alias エイリアス名=’コマンド群’

※function 引数を持たせる定義
│ function 関数名() { … $1…; };

⑦設定の再読み込み
│ source ファイル名

⑧リソース制限
│ ulimit -a 制限値を表示
│ ulimit -c コアダンプのサイズ
│ ulimit -f シェル上で生成できるファイルの最大
※数値を与えず、uulimitedとすれば無制限。

⑨コマンドを探す
│ type コマンド名
※whichでは外部コマンドに限られる。typeでは内部、エイリアスとも表示される。

⑩バックグラウンドジョブのプロセスID表示
│ jobs

⑪フォアグラウンドに変更する
│ fg ジョブ番号

⑫バックグラウンドに変更する
│ 実行中のジョブに対して ^Z を与えて一時停止させた上で、
│ bg ジョブ番号

_◇letと数値演算

※$(( ))ブロック
例)
$var=$(($var+1))

例)

function myfunc1
{
        var=$((var+1))
        echo "func=>$var"
}
var=1
echo "main=>$var"
myfunc1
echo "main=>$var"

整数演算
※letの引数として変数名を書くときには頭に$をつけなくても良い
例)
let num2=num-1

_◇function

書式)
[function] name() { commands; }

例)
$ function dir() { ls -l $* | grep ‘^d’ ; }

⇒変数は大域なので、関数内で変更すればその外でも見える。
⇒関数内でコマンドライン引数を含む各種変数を参照することもできる

※IFS変数を定義することで引数の区切り文字を替えることができる。

例)
直接echoしている$#は,を区切りとして認識しないが、関数内では、,を区切りとして認識する。

IFS=,
echo "$# ... arguments"
function countarguments
{
    echo "$# ... count arguments."
}
countarguments $*

_◇help
組み込みコマンドのヘルプ

help string


◆ジョブ制御

_◇ジョブ制御
bg
│ ジョブを裏で実行
⇒IDを指定しないとカレントジョブを裏で実行(CTRL-zでカレントをサスペンドした後)
⇒IDを指定するとIDのジョブを裏で

fg
│ ジョブを表で実行

jobs
│ 実行中のジョブ一覧

kill
│ ジョブ終了

stop
│ 裏ジョブ一時停止

stty tostop
│ 裏ジョブが端末に出力しようとしている場合、そのジョブの実行を止める

wait
│ 裏ジョブが終了するまで実行中段
⇒IDを指定しないと全ての裏ジョブ終了まで待つ
⇒IDを指定すると該当の裏ジョブ終了まで待つ。
※$!には最後の裏プロセスのID番号が入っている
$ wait $!

CTRL-z
│ 表ジョブをサスペンドし、入力を受け付ける。これによりfg, bgコマンドが使用できる。

_◇コプロセス
│ cmd1 | cmd2 |&
パイプラインを裏で実行。双方向パイプをセットして標準入出力をリダイレクトできるbash機能

①read -p var
コプロセスの出力を変数varに読み込む

②print -p string
コプロセスに文字列を書き込む

③cmd <&p
コプロセスからコマンドへの入力を受け取る

④cmd >&p
cmdの出力をコプロセスへ渡す。

_◇シグナルトラップ

書式)
trap -l
│ シグナルの一覧を表示

trap コマンド シグナル
│ シグナルを受信したらコマンドを実行

trap “” シグナル
│ シグナルを無視

trap シグナル
│ シグナル受信時の動作をデフォルトに戻す

trap
│ その時点で割り当てられている内容

例)
trap “echo ‘INT signal recieved’;exit” INT
⇒INTを受信したらその旨表示して終了

trap dispatch INT
⇒INTを受信したらシェル関数dispatchを呼び出す。


◆変数

_◇変数の設定と解除
│ name=[value]
valueを省略すると値が空にセットされるが変数は存在する。
│ unset name
により変数は消去される

※変数に代入する=の前後にスペースは入れないこと!

※declareによる設定
変数の型を設定することができる

例)整数型にしばり
declare -i a=1 b=2

例)
declare -i a=1 b=2
let c=$a+$b
echo “$a + $b = $c”

_◇変数置換
│ ${varname}
により変数の値が返される。変数名に誤解の無いケースでは{}は省略できる。

<代替演算>
│ ${varname:-word}
│  値が空でなければ変数の値を返すが、値が空ならwordを返す。
│ ${varname:=word}
│  値が空でなければ変数の値を返すが、値が空ならwordをセットした上で返す。
│ ${varname:?message}
│  値が空でなければ変数の値を返すが、値が空ならメッセージを表示してコマンドを終了する。
│ ${varname:+word}
│  値が空でなければwordを返すが、それ以外なら空を返す。変数が定義されているかどうかを確かめられる。例)${count:+1} countが定義されていれば1(真)

<パターン照合演算>
│ ${variable#pattern}
│  値の先頭がパターンマッチした場合、最短マッチの残りの部分を返す。
│ ${variable##pattern}
│  値の先頭がパターンマッチした場合、最長マッチの残りの部分を返す。
│ ${variable%pattern}
│  値の末尾がパターンマッチした場合、最短マッチの残りの部分を返す。
│ ${variable%%pattern}
│  値の末尾がパターンマッチした場合、最長マッチの残りの部分を返す。

_◇位置パラメータ、特殊変数、組み込みシェル変数

(1)$@,$*
│ すべての位置パラメータをならべたもの。区切りが違う。
(2)$#
│ 位置パラメータの個数を10進数であらわしたもの
(3)$?
│ 直前のフォアグラウンドジョブの戻り値
│ 終了ステータス
(4)$-
│ オプション値
(5)$$
│ 現在のシェルのプロセスID
(6)$!
│ 最後に実行された裏ジョブのプロセスID
(7)$0
│ シェルスクリプト名
(8)$_
│ 直前のコマンド展開後の最後の引数
(9)基本シェルオプション
│ set -oで設定する。
│  emacs Emacs編集モード
│  ignoreeof ^Dによるログオフをある程度無視
│  noclobber 通常リダイレクトでの上書き禁止
│  noglob ワイルドカード展開抑止
│  notify 裏ジョブ終了即通知
│  nounset 未定義変数参照時はエラー
│  vi vi編集モード
(10)標準変数
│ COLUMNS 画面桁数
│ EDITOR エディタのパス
│ LINES 画面行数
│ SHELL シェルのパス
│ TERM 端末の種類

(11)履歴変数

_◇スクリプトのコマンドライン引数
$0
│ コマンド名自身
$1,$2
│ コマンドライン引数。
$*
│ $1から全てをまとめて
※スペースを含んだ引数を与えたいときには””もしくは”で囲む。

$#
│ 位置パラメータの個数

_◇特殊変数

$? 直前の表ジョブの戻り値
$$ 現在のシェルのプロセルID
$! 最後に実行された裏ジョブのプロセスID
$0 シェルスクリプトの名前


◆TIPS

_◇一時的に環境変数の値をセットして実行
$ 環境変数=値 プログラム名 引数…

※プログラムに渡される引数はプログラム名以降、通常の順番と数。

_◇条件判断

if [ "$arg" = "yes" ]; then
  ...
fi

のように記述する。

変数 $arg をダブルクオートで括るのは、

①$argが空。
②$argに空白で区切られた複数の値が入っている。

場合でも、問題なく動かすため。

※if の条件判断に使われている [ は、コマンド test の別名である。] はコマンドの引数である。testは [ という名で呼ばれると、必ず最後の引数として ] を要求する。
⇒よって [ と ] の前後は必ずスペースで区切る。

_◇PATH

パスの設定例)
$ export PATH=~/scripts:$PATH

※カレントディレクトリの状態によって、実行されるコマンドが変わることを避けるため、UNIX系ではパスにカレントを含めないことが多い


◆環境変数 embv

設定
例)
export KBUILD_VERBOSE=1

_◇IFS(Internal Field Separator)
「引数と引数の間」などの区切りを表す文字のリスト

※通常「スペース」「タブ」「改行(newline)」

$ echo -n “$IFS” | od -a
0000000 sp ht nl
0000003
$ echo -n “$IFS” | od -b
0000000 040 011 012
0000003
$ echo -n “$IFS” | od -c
0000000 \t \n
0000003

※echoコマンド自体が改行を出力しないよう-n
※位置パラメータ変数$*の引数の区切り文字には,デフォルトではIFSの最初の文字が使われる。

_◇PS1
シェルのプロンプト

_◇PS2
シェルのプロンプト

_◇LANG

例)
│ export LANG=C

_◇PWD
カレントディレクトリ

_◇HOSTNAME
ホスト名

_◇USER
ユーザ名

_◇TERM
ターミナル名

_◇MACHTYPE
マシンアーキテクチャタイプ

_◇MAIL
メール保存フルパス

_◇HOME
ホームディレクトリ

_◇PATH
プログラム検索パス

_◇SHELL
シェル

_◇HISTSIZE
コマンド履歴最大数

_◇HISTFILE
コマンド保存ファイル


◆例

_◇.bashrc

※シンプル

#
PATH=$PATH:~/bin
export PATH
EDITOR=vi
export EDITOR
export LANG=ja_JP.EUC-JP
export PAGER=less
ulimit -c 0
※コアダンプを作らない。
umask 022
※新規ファイルのパーミッションは-rw-r--r--
alias ls='ls -F'

※mingw64用(SJIS端末)

export TERM=msys
export LS_COLORS="no=00:fi=00:di=01;34:ln=00;36"
export CC=gcc
export CFLAGS=-O2
export CXXFLAGS=-O2
export LANG=ja_JP.SJIS
export OUTPUT_CHARSET=SJIS
alias ls='ls -F --color=auto --show-control-chars'
source /etc/git-prompt.sh
PS1='[\[\033[32m\]\u@\h\[\033[00m\]:\[\033[33m\]\w\[\033[31m\]$(__git_ps1)\[\033[00m\]]\n\$ '

if [ -f /etc/bashrc ]; then
./etc/bashrc
fi

PATH="$PATH":/graphviz/bin:/winbin

function dotPng {
  if [ $# -eq 0 ]; then
    echo no dot file
  else
    dot -Tpng $1.dot -o $1.png
  fi
};

_◇.bash_profile
Ubuntuでは、.profile

#
function cc() { gcc $1.c -o $1; }

_◇スクリプトファイル

①スクリプトの引数などチェックして実行

#!/bin/bash
# 引数の数チェック
if [ $# -lt 1 -o $# -gt 2 ]; then
echo “Usage: rec_grep expr [directory]”
exit 1
fi
# 第2引数セット(省略された場合カレントディレクトリ)
if [ -n “$2″ ]; then
DIR=”$2″
else
DIR=”.”
fi
# ディレクトリ存在チェック
if [ ! -d “$DIR” ]; then
echo “$DIR” ” is not a directory”
echo “Usage: rec_grep expr [directory]”
exit 1
fi
# コマンド実行
grep -s $1 `find $2 -type f 2> /dev/null`
exit $?


☆C shell


◆環境変数の設定

例)
setenv KBUILD_VERBOSE 1