naobe @ ウィキ
ksh
最終更新:
Bot(ページ名リンク)
-
view
Linuxに戻る
.profile
ログイン起動スクリプト
.kshrc
シェル初期起動スクリプト。/bin/kshを手動で実行したときに動くスクリプト。
【設定例】
【設定例】
PATH=$PATH:. # fcを実行したときのエディタ export FCEDIT=vi # Emacsモード。履歴を修正するときにEmacsのキーバインディングを使用可能 set -o emacs alias l='ls -F' alias ll='ls -alt' alias rm='rm -i'
プロンプトの変更
.profileに以下を追加すると、[ユーザ@ホスト 現ディレクトリ]$ がプロンプトになる。
PS1='[$USER@$HOSTNAME ${PWD##*/}]\$ '
履歴
historyコマンドで、過去のコマンド履歴表示。historyはfc -lのalias。bashと機能は同じではないかな?
history 10 履歴番号10以後すべて表示 history -10 過去10件の履歴表示 history 10 10 履歴番号10を表示 history 10 100 10~100の履歴を表示
$ history 322 ps -ef 323 ps -ef | grep back 324 print -p 2 325 read-p x 326 read -p x 327 read -p 328 ps -ef | grep back 329 ps -ef | grep back 330 kill 23262 331 ps -ef | grep back 332 history 333 321 334 !321 335 man ksh 336 man history 337 history
FCEDIT=/bin/viとしておくと、fc 履歴番号 で、viにコマンド表示。viで編集して終了すれば、コマンドを実行する(途中やめできない。編集しなければ前のコマンドを実行するので注意が必要。)。直近の履歴なら、set -o emacsにしておいて上矢印でコマンド履歴をたどれる。
安全に実行できるスクリプトを作成してみた。
#!/bin/ksh
#
# 履歴を指定して過去のコマンドをファイルに格納する。
# 対話的に実行を確認して、編集後のコマンドを実行する。
#
usage() {
echo "usage: rireki history_num $1"
}
exec_cmd() {
. /tmp/${USER}_cmdline
}
ptn_match() {
echo $1 | egrep -q $2
}
if [ $# -eq 0 ]; then
usage ;
exit 1
fi
ptn_match $1 '^[1-9][0-9]+'
if [ $? -ne 0 ] ; then
usage "引数が数値でない"
exit 1
fi
HISTORY_NO=$1
fc -ln $HISTORY_NO $HISTORY_NO > /tmp/${USER}_cmdline
echo -n "コマンドを保管しました。コマンドを編集しますか(y/n) "
read ANS
ptn_match $ANS '^(y|yes)$'
if [ $? -eq 0 ]; then
vi /tmp/${USER}_cmdline
echo -n "実行しますか(y/n) "
read ANS2
ptn_match $ANS2 '^(y|yes)$'
if [ $? -ne 0 ]; then
exit 0
fi
exec_cmd ;
else
exec_cmd ;
fi
スクリプト
((...))構文
(())の中で、C言語と同様の計算式を使える。戻り値はtruer/falseで、if, whileの条件式として使える。forの条件としても使える。(())の中では変数を表すのに$は不要(あっても構わない)。$((...))は計算式の結果を変数として扱う。
for(( i = 0 ; i <10 ; i++ ))
do
echo $i
done
AA=$((1.5 + 2.2))
echo $AA
((AA = 1.5 + 2.2))
echo $AA
#
echo 計算式の評価
r=30
echo r = $r
((pi = 4.0 * ( 4.0 * atan(1.0/5.0) - atan(1.0/239.0) )))
echo pi = $pi
((enshu = pi * 2 * r))
echo enshu = $enshu
echo
この機能はabs、acos、asin、atan、cos、cosh、exp、int、log、sin、sinh、sqrt、tan、tanhなどの数学関数と一緒に利用できる。
ループ
Bourn Shellと同様
【例】
while
#
# コマンドパラメータを順次出力
#
for param
do
echo $param
done
#
# ファイル読み込み
#
# 改行文字がセパレータなので1行ごとに表示される。
# 何故か、この場合、ブランク、タブはセパレート文字にならない
#
#for line in `cat /etc/passwd`
for line in $(cat /etc/passwd)
do
echo $line
done
for(( i = 0 ; i < 10 ; i++ ))
do
echo $i
done
#
# select, ifテスト
#
select name in aaa bbb ccc
do
echo $name
# パターン一致ではない
if [[ $name == ccc ]]
then
break
fi
done
#
# select, ifテスト
#
select name in aaa bbb ccc
do
echo $name
# パターン一致ではない
if echo $name | egrep -q '^cc.*'
then
break
fi
done
#
# caseテスト
#
read name
case $name in
aaa)
echo AAA
;;
bbb)
echo BBB
;;
esac
#
# while
#
file="/etc/passwd"
IFS=:
while read user passwd userid grpid comment homedir interpret
do
echo $user $homedir $interpret
done < $file
変数
typeset
関数内で使用すると、ローカル変数になる。関数は、function func_nameの形式で書かないと有効にならない(CentOS)。
【例】 # # typeset フォーマット変換 # name=abc name2=abc number1=123 # 左詰め、桁数5 typeset -L5 name echo "###$name###" typeset -L5 name=def echo "###$name###" # 右詰、桁数5 typeset -R5 name2 echo "###$name2###" # 右詰、桁数8、0埋め typeset -Z8 number1 echo "###$number1###" 【実行結果】 ###abc ### ###def ### ### abc### ###00000123###
単純な変数
【例】
echo 単純な変数 var=aaa echo $var echo
複合変数
構造体のような変数
【例】
【例】
#!/bin/ksh
person=(
name=""
sex="male"
age=""
)
eval "bill=$person"
bill.name=bill
bill.age=32
eval "sally=$person"
sally.name=sally
sally.sex=female
sally.age=21
echo "bill: name=${bill.name} sex=${bill.sex} age=${bill.age}"
echo "sally: name=${sally.name} sex=${sally.sex} age=${sally.age}"
配列
【例】
#
# 配列
#
echo 一度に代入
array=(a b c d)
#
# 中括弧を記述しないと、$arrayが先に評価される。
echo ${array[0]}
echo $array
echo ${array[3]}
echo ${array[*]}
echo
#
echo 個々に代入
array[0]=A
array[1]=B
array[2]=C
echo ${array[0]}
echo ${array[1]}
echo ${array[2]}
echo
連想配列
【例】
#
echo 連想配列
typeset -A hash
hash=([key1]=val1
[key2]=val2
[key3]=val3)
echo hash[key1]=${hash[key1]}
echo hash[key2]=${hash[key2]}
echo hash[key3]=${hash[key3]}
echo
関数
基本的な関数
【例】
#
# 基本的な関数
function add {
return `expr $1 + $2`
}
add 1 2
echo 1 + 2 = $?
ディシプリン関数
変数をget,set,unsetしたときに起動する関数。変数の値を自動的に変える。たとえば円の半径を変えた時に演習を自動的に変えたいときに使う。変数の値はシェルの特殊変数である.sh.valueに設定する。
#
# 半径から円周、面積を求める
((pi = 4.0 * ( 4.0 * atan(1.0/5.0) - atan(1.0/239.0) )))
## 複合変数
en=(
float hankei
float enshu
float menseki
)
#
# 円周のディシプリン関数
function en.enshu.get {
(( .sh.value = 2 * pi * en.hankei ))
}
en.hankei=2.
echo hankei : ${en.hankei}
#
# 円周を求めるときにディシプリン関数が起動される(半径を変えると自動的に円周が変わる)。
echo enshu : ${en.enshu}
コプロセス
コプロセスとは、双方向のパイプ。|&を使って、プロセスをバックグラウンドで起動すると、print -p, read -pを使ってバックグラウンドプロセスとデータのやりとりができる。
【例】 back.sh total=0 while ["" == ""] do read input (( total = total + input )) echo $total done $./back.sh |& $ print -p 2 $ read -p x; echo $x 2 $ print -p 10 $ read -p x; echo $x 12 $ print -p 100 $ read -p x; echo $x 112
