======================================================================
Bourne Shell ϥ륹ץȽ by Taiji Yamada <taiji@aihara.co.jp>
======================================================================

Υ륹ץȽ Bourne Shell ϥμפʵǽưǧ
뤿ΤΤǤޤƼ Bourne Shell ϥ(sh, ksh, bash,
zsh, ash)μΰ㤤ͽǧ뤿ˤͭѤǤ

㤨С

	$ sh   04evalexpr_doubleparen_float.sh
	$ bash 04evalexpr_doubleparen_float.sh
	$ zsh  04evalexpr_doubleparen_float.sh
	$ ksh  04evalexpr_doubleparen_float.sh
	$ ash  04evalexpr_doubleparen_float.sh

ʤɤΤ褦˼¹Ԥơ񤫤Ƥ륹ץȤƼ亮ǰտޤ̤
ư뤫ǧǤޤäˡ쥬ʴĶ䥷Ȥȥ顼
ˤʤ뤳Ȥθӳƥޥ˥奢ڡȹͻ̤ơ륹
ƥ󥰤򿼤뤳ȤڤǤ

ʲ˼פʥȥԥå˲դƤޤ


--------------------
echo -n μΰ㤤
--------------------

echo ǲԤԤʤʤ -n ץϡɬ⤹٤ƤΥǼ
Ƥ櫓ǤϤޤ

	echo -n "Hello, "
	echo "world!"

⤷Ʊθ̤ΤǤСprintf ޥɤѤƤ
ɤǤ礦

	printf "%s" "Hello, "
	echo "world!"

: 00echo_-n.sh, 00printf.sh


----------------
դѿ
----------------

ˤϰʲΤ褦ʼबޤ

		var==NULL	undefined(var)	otherwise
${var:-str}	str		str		$var
${var:=str}	var=str		var=str		$var
${var:?str}	顼		顼		$var
${var:+str}	NULL		NULL		str

${var-str}	NULL		str		$var
${var=str}	NULL		var=str		$var
${var?str}	NULL		顼		$var
${var+str}	str		NULL		str

ܤϤ줾Υޥ˥奢ڡ򻲾ȤΤȡ

: 01variables.sh, 01variables_conditional.sh


--------------------
ޤե̾
--------------------

ޤե̾ Unix ǤϤޤȤޤ󤬡갷ʤ櫓
ǤϤޤ󡣤ץȤεҤˤϥ֥륯Ȥǳʤɤ
դɬפޤ

ե̾˸¤餺ֶޤĤΰפɽƱͤǤ

: 02variables_doublequote.sh


------------------
Υޥִ
------------------

 POSIX ΥޥִǤ

	$(command) 

Ūʥޥִ

	`command`

ͥȤΤ䤹ͥƤޤŤǤбƤޤΤǡ
äɬפʤ¤ꡢŪʥޥִޤƤ̵Ǥ

: 03command_backquote.sh, 03command_dollparen.sh


------------------
ŸȻɾ
------------------

 POSIX λŸ

	$((expression))

ksh ϤȤ bash  zsh ǤѲǽǤݡӥƥ
뤹̤Ǥϡ expr ޥɤ bc ޥοɬ
פǤ礦ξ塢ư黻ǽǤȤϸ¤ʤ
ޤ󡣤ξϡbc -l ޥɤѲǽǤ

Ʊͤ for ((i=1; i<=10; i++)) Τ褦ʻɾݡӥƥŻ뤹
̤Ǥϡ while 롼פ expr ޥɤοɬפ
礦

âޥɤ¿Ѥ®ǽΤǡݡӥƥ
뤹ʤɤ󤬤ʤˤϡŸӻɾ϶ˤͭǤ

: 04evalexpr_doubleparen.sh, 04evalexpr_doubleparen_float.sh,
      04evalexpr_bc.sh, 04evalexpr_expr.sh,
      10expr_doublepalen.sh,
      16lists_commands.sh, 16lists_commands_posix.sh


---------------
$*  $@ ΰ㤤
---------------

"$*" ϰζڤեɥѥ졼$IFS֤ޤ"$@" 
ϰζڤ꤬ݻޤ̤ǻȤʬΤפǤ

: 05heredocuments.sh, 06for_in.sh, 10expr_doublepalen.sh,
      16lists_commands.sh, 16lists_commands_posix.sh


-----------------
test  [ ڤ [[
-----------------

Ūʼɾ[פμΤ test ޥɤǤ뤳ȤΤޤ礦ޤ
ɽ[פϻȤ鷺 test 侩̤ʤ餺ޤ(㤨С
Autoconf ΥǤεҤʤ)

ޤtest ޥɤޥɤȤưƤ硢bash  zsh 
ȼγĥǽ򤽤ȤΤ餺˻ȤäƤꡢҤʤȤ鳰ޥ
ɤ test Ȥ줿ˡΥץȤտޤʤưȤʤȥ֥
⤢ޤͽȥ֥򤹤ˤϡBourne Shell ޤ POSIX 
 test ޥɤεǽ˸¤äƻȤ褦ˤ뤳Ȥݡӥƥ
Ż뤵̤ǤϿ侩ޤ

 POSIX μɾ[[פ ksh ϤȤ bash  zsh ǤѲǽ
ݡӥƥŻ뤹̤ǤϡŪ Bourne Shell 
ϼƤʤȤ顢ޤȤޤ

Ȥϸtest ޥɤμǤϡ

	if [ expr1 -a expr2 -a expr3 ]; then
	  :
	fi

ưʤĶ⤢뤽Ǥȥ֥򤱤뤿ˤϡ

	if [ expr1 ] && [ expr2 ] && [ expr3 ]; then
	  :
	fi

Τ褦˽񤯤 POSIX ߴΥ˸ꤷơ

	if [[ expr1 && expr2 && expr3 ]]; then
	  :
	fi

Τ褦˽񤯤ȤˤʤǤ礦2ܤΡ&&פˤĤƤϸҡ

: 08expr_bracket.sh, 08expr_bracket_-a.sh, 09expr_doublebracket.sh


------------------------------------------
ޥɥ饤 shift ڤ set 
------------------------------------------

ޥɥ饤˥ץ󤬤Ȥϡ shift Ǿ񤷤ʤ
while 롼פǽΤʤǤ

	while [ "$#" != 0 ]; do
	  case "$1" in
	  -h|--help) usage "$@"; exit 0;;
	    :
	  *) break;;
	  esac
	  shift
	done

: 11while_shift_case.sh


Υޥɥ饤Τ褦ˡʣʸҤȤĤĽ
ϡset ޥɤʣʸ "$@" ѿ˳Ǽм¸Ǥޤ

	set Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
	while [ "$#" != 0 ]; do
	    :
	  shift
	done

 POSIX Ȥ "$@" ˼¸Ǥޤ
μǤ ksh, bash, zsh 줾̯˵ưۤʤޤΤǡݡ
ӥƥŻ뤵̤ǤϡϤޤȤޤ

äˡѿ򤤤ɤꤹˡ䡢κݤγϤźۤʤ
դǤ

ksh)

	set -A months x Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
	echo ${months[11]}

bash)
	months=(x Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec)
	echo ${months[11]}

zsh)
	months=(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec)
	echo ${months[11]}

	set -A months Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec 
	echo ${months[11]}

äơʲΤ褦ѿ򤷤̵Ǥ

	i=1
	for month in Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec; do
	  months[$i]="$month"
	  ((i++))
	done

: 12set_eval.sh, 12set_array.sh


------------------------
ޤʸΥꥹ
------------------------

ե̾ʤɶޤʸΥꥹȤϾҤ "$@" Ȥʤ
ǥ󥰤˻ˤʤ꤬Ǥ⤦ҤȤĤΤȤơwhile 
ʸ read ޥɤȤäưԤĽˡ褯Ȥޤ

	cat <<EOF | while read month; do
	  :
	EOF
	  echo $month
	done

ϥҥɥȡ<<EOF : EOFפ while read Ȥ߹碌Ǥ
ǾάԤEOFʳǤդʸ󤬵ҤǤΤǡޤʸ
ΥꥹȤνñ˼¸Ǥޤ

: 13while_read.sh 


------------
test  eval
------------

ѿvar1, var2ʸ""פǤǽθȡʲΥ

	if [ x"$var1" = x"$var2" ]; then : fi

Τ褦ʽ侩̤ޤȤΤ⡢ʸΰ
ˤäưۤʤ뤫Ǥϡx ץեåפȸƤФƥ˥
ǤߤۤȤɤμǡʲΥɤǤꤢޤ

	if [ "$var1" = "$var2" ]; then : fi

eval ޥɤˤϤΡx ץեåפͭѤ
ʤޤȤơ

	for var in LANG LC_ALL LC_CTYPE LC_MESSAGES LANGUAGE; do
	  if eval [ x"\${$var+set}" = x"set" ]; then
	    eval $var=C
	  fi
	done

ΥץȤǡx ץեåפ̵ eval ˰տޤ̤˰
Ϥ餺˥顼Ȥʤޤ⤷x ץեåפȤʤϡ
ʲΤ褦˥Хååˤ륨פɬפˤʤޤ

	for var in LANG LC_ALL LC_CTYPE LC_MESSAGES LANGUAGE; do
	  if eval [ \"\${$var+set}\" = \"set\" ]; then
	    eval $var=C
	  fi
	done

ʤߤˤΥץȤϡLANG, LC_ALL ʤɤδĶѿͤꤵ
ȤΤߡƤCפ֤ΤǡAutoconf  
configure ץȤǸޤäȤ⡢ǿ configure 
ȤǤ̤μ¸ˡ֤Ƥ褦Ǥ

: 14eval_test.sh, 14eval_test_escape.sh


---------------
function μ
---------------

ؿ foo(){ : } 򥵥ݡȤʤǤΡεǽؤѰդ뤳
ȤϺǤΤǡݡӥƥŻ뤹̤Ǥϡؿޤä
ʤ⤷ϡ¹Ի˿ΥؤʤɤˡΤ
뤳Ȥ¿褦Ǥ

ؿ򥵥ݡȤʤϵǤꡢġؿ϶ˤͭѤ
Τǡؿ򥵥ݡȤʤѤΤΤ侩ޤ

: 15functions.sh


---------------
ꥹȤ &&, ||
---------------

if, while  until 湽ʸˤĤŤʸϥޥɤ䥳ޥɤʤ
ȤǤ뤳Ȥ򤹤ȡ

	if [ expression ]; then
	  echo true
	else
	  echo false
	fi

ϰʲΤ褦ˤ񤱤뤳Ȥ狼Ǥ礦

	[ expression ] && echo true || echo false

ǡ&&פľΥޥɤ֤͡$?פ0Ĥޤ꿿ΤȤ˼Υ
ޥɤꥹȤ¹Ԥ||פ֤͡$?פ0ʳĤޤ굶ΤȤ˼
Υޥɤ¹Ԥޤ

˲ʤơꥹȤϡ{ list; }פΤ褦˥֥쥤Ȥäƥ롼
ǤΤǡ㤨С

	if [ expression ]; then
	  echo true
	  state=1
	else
	  echo false
	  state=0
	fi

ϰʲΤ褦˽񤱤뤳ȤȻפޤ

	[ expression ] && { echo true; state=1; } || { echo false; state=0; }

νѤ϶ʪǤ㤨СŤǤϡ֥쥤
ƻȤ줿$?פ֥쥤˽Ф˸ͤξ硢
ξΥ֥饱åȤƤޤȤտޤʤưˤʤ뤫Τ
󡣤ޤμǤ⡢֥饱åǸΡ;פ򤦤ä˺줿
ˡưϤ뤬$?פͤƱͤΰտޤʤư⤿
餹Ȥ⤢ޤ

äơä˻𤬤ʤˤ̤ if ʸѤ̵Ǥ

: 16lists_commands.sh, 16lists_commands_posix.sh


-------------------------
"$@" ȿΥޥִ
-------------------------

֥륯Ūʥޥִ "$@" Ȥϡ\"$@\"
Τ褦˥Хååˤ륨פɬפˤʤޤ

	echo "$* = `expr \"$@\"`"

: 16lists_commands.sh


֥륯ǿ POSIX Υޥִ "$@" Ȥ
ϡΤ褦ʥפפǤ

	echo "$* = $(expr "$@")"

: 16lists_commands_posix.sh


--------------------------
ҥɥȤѿŸ
--------------------------

ʲΤ褦˥ҥɥȤȤȽϤʸ̤Τޤ޽񤱤ޤ

	cat <<EOF
	$0 - the name of the file.
	EOF

ѿŸʤɤϤξԤʤƤޤΤǡΤˤϡ֤Τޤޡ
Ȥ櫓ǤϤޤѿŸ޻ߤˤϡʲΤ褦 EOF 
ȤФ褤ΤǤ

	cat <<'EOF'
	$0 - the name of the file.
	EOF

: 17here_documents.sh


------------
ץִ
------------

եե륿̤Ƥ硢ʲΤ褦˥ѥפ
Ф褤ΤǤ

	nkf -u README.txt | sed -e 's///g;s///g'

ե륿ե뤬İʾȡäˡϺΤޤ
ξ硢 POSIX Υץִ<(command)פȤȰʲΤ褦
ʣΥեե륿̤Ǥޤ

	diff -u <(nkf -u README.txt~) <(nkf -u README.txt) | less

ǰʤץִ<(command)פ³ե뤬̾
ΥեǤϤʤΤǡ˰ʤץ(lseekɬפȤץ
)ޤϡzsh ʤˡ=(command)פȤ


	mgdiff =(nkf -u README.txt~) =(nkf -u README.txt)

â zsh ȼǽʤΤդɬפǤ


: 18process_subst.sh


------------------
:פ true
------------------

̥륳ޥɤǤ륳:פϰ̵뤹ΤǡʲΤ褦˥
ԡ#פǤ뤫Τ褦˻Ȥͤ⸫ޤ

	: comment line

ʲΤ褦ˤϤɤΤ褦ư򤹤Ǥ礦

	: comment line && echo true || echo false

ϡ̥륳ޥɤǤ륳:פϾ˿֤Τǡtrue ɽ
ޤĤޤޤǥȤȤ̵뤹#פȤϤϤۤʤΤǡ
Ѥ϶ʪǤ

ʲΤ褦ʥȹԤʤ顢ʣԤΥȤ񤱤ΤͭѤǤ

	: <<'EOF'
	comment lines
	until a line containing only EOF
	EOF

Ǥϥ󥰥륯Ȥ EOF ѤƤ뤳ȤפǤʤ
С˥ޥִν񼰤˹礦Τäˡտޤ
ޥɤ¹ԤƤޤޤ


ޤˤϥץߥ󥰸CΤ褦ʥ֥åȡ/* ... */
ޤ󡣤ǡ󥳥ޥִˤäƥ֥åȤ˻
Τ¸뤳Ȥޤ

	echo shell does not support block comments
	echo but it`: commant substitution` will be an empty string like block comments.

äơ嵭ΥХåȤ˰Ϥޤ줿ϰϤ϶ʸˤʤޤ¹Ԥ
ʤ櫓ǤϤʤޤǡʸؤִǤΤǡϰռ
ɬפϤޤ


ơ̥륳ޥɤǤ륳:פˤϤäͭʻȤޤ
Τ褦˥ե饰ȤƻȤΤǤ

	flag=:
	if $flag; then
	  echo flag is ON
	else
	  echo flag is OFF
	fi

:פޥɤʤΤǡflag=trueפȤƳޥɡtrue
ƤФΨ褤ΤǤ

Ǥϡǥե饰˵ƤϤɤФΤǤ礦
ϳޥɡfalseפȤ¾ʤ褦Ǥ

	flag=false
		:

⤷ϥؿ false ƤޤäƤ褤⤷ޤ

	false(){ return 1; }
	flag=false
		:


: 19colon.sh, 19colon_true.sh


-----------------------------------
쥯Ȥ xargs vs. while read
-----------------------------------

ѥ˹פʣΥե뤿ˡ褯ʲΤ褦
xargs λȤҲ𤷤Ƥ륵Ȥޤ

	find . -name '*~' -print | xargs rm

ȶޤեΤȤ˻Τޤäơ
ʤȤʲΤ褦ˤʤФʤޤ

	find . -name '*~' -print0 | xargs -0 rm

ȡեζڤ꤬ʥʸȤʤΤǡΤϵʤ
ʤޤ

xargs ʣʤȤ餻褦Ȥü񤷤ʤޤ
Τǡxargs Ȥ鷺ˡξʤ顢ʲΤ褦ˤФ褤ΤǤ

	find . -name '*~' -print | while read f; do
	  rm "$f"
	done

ȡԤեζڤˤʤΤǡʸޤեΤȤ
λΤʤˡεǽΤޤ޻ȤΤǱѤ
ޤ


: 20redirection_while_read.sh


----------------------------------
쥯Ȥɸϡ顼
----------------------------------

륳ޥɤ¹Ԥʤ顢ɸϤȥ顼ϤΥϿƤ
ϡ̾ʲΤ褦ˤޤ

	make 2>&1 | tee make.log

>פɸ(fd=1)Ǥ2>פȤȥ顼(fd=2)
Ȥˤʤޤˡ2>&1פϥ顼(fd=2)ɸϤɸ
(fd=1)˽žޤơtee ޥɤϰΥեɸ
ϿʤɸϤ륳ޥɤʤΤǡ嵭Ūãޤ

zsh  csh ϥ饤ʰʲξάȤޤθʤΤǿ侩Ǥ
ޤ

	make |& tee make.log

ޤzsh ¿Žϵǽˤ tee ʤƱͤΤȤǽǤ

	make > /dev/stdout > make.log 2>&1

Ĥ zsh ʳưȰտޤưˤʤޤΤǿ侩Ǥޤ


1>&2פɸ(fd=1)ȥ顼Ϥ򡢥顼(fd=2)˽ž
ޤäơʲϥץߥ󥰸CǤfprintf(stderr, "error\n")
ƱȤˤʤޤ

	echo "error!" 1>&2

ɸ(fd=1)ϾάǤΤǡʲƱ̣ǤΤȶ̤䤹
ΤǡȤ褦ˤޤ礦

	echo "error!" >&2


ơ륳ޥɤ¹Ԥʤ顢ɸϤȥ顼ϤΥϿ
Ƥǡ̤˽ϤʤƤ褤ȤˤϡѥפȤä
tee ƤɬפϤޤ

	make > make.log 2>&1

ְä tee ΤȤߤʲΤ褦˽񤤤Ƥޤȡ顼ϤϿ
ޤ

	make 2>&1 > make.log

ʤʤ2>&1פϺΥޥɤɸϤȥ顼Ϥ˺ѤΤ
Ǥäơtee make.log 2>&1פ tee Υ顼ϤɸϤإ
쥯ȤǤ

ñˡ顼ϤΤߵϿϡʲΤ褦ˤʤޤ

	make 2> make.log


: 20redirection_tee.sh, 20redirection_tee_like.sh, 20redirection_stderr.sh, 20redirection_stderr_only.sh
