64
#ssmjp 2013.09.25. @th0x0472 MAN OF BASH INTO DEEPNESS

MAN OF BASH #ssmjp 2013.09.25

Embed Size (px)

Citation preview

Page 1: MAN OF BASH #ssmjp 2013.09.25

#ssmjp 2013.09.25.@th0x0472

MAN OF BASHINTO DEEPNESS

Page 2: MAN OF BASH #ssmjp 2013.09.25

祝!Sphinx本発売

http://www.oreilly.co.jp/books/9784873116488/

Page 3: MAN OF BASH #ssmjp 2013.09.25

サマリー。最近たくさんシェルスクリプト書いた。

bashのmanを読んだ。

イロイロできるじゃん、すげー!

というわけで、manで調べたこと、試したことを整理してシェアしますよ。

Page 4: MAN OF BASH #ssmjp 2013.09.25

ディープと感じるかどうかは個人差があります。

ディープと感じるかどうかは個人差があります。

大事なことなので2回言います。

Page 5: MAN OF BASH #ssmjp 2013.09.25

正直、色々できすぎておなかいっぱい。今回は変数展開。

「今回は」といいましたが、次回があるかは僕の検証能力次第です。

コマンドラインの操作をラクにするアレコレもありません。

Page 6: MAN OF BASH #ssmjp 2013.09.25

まずはおさらい% cat ./example0.sh

#!/bin/bash -x

VAR="bar"

echo ${VAR}

echo $VAR

Page 7: MAN OF BASH #ssmjp 2013.09.25

実行すると./example0.sh

+ VAR=bar

+ echo bar

bar

+ echo bar

bar

Page 8: MAN OF BASH #ssmjp 2013.09.25

${VAR}

このとき、変数名のあとに記号+アルファ付けるとイロイロできます。

Page 9: MAN OF BASH #ssmjp 2013.09.25

Use Default Values.word に指定した値がデフォルト値になる。

parameter に値が代入されていれば、その値が使われる。

parameter になにも代入されていなければ、デフォルト値が使われる。

parameter に word は代入されない。

${parameter:-word}

Page 10: MAN OF BASH #ssmjp 2013.09.25

${parameter:-word}#!/bin/bash -x

echo ${VAR}echo ${VAR:-"foo"}

echo ${VAR}

VAR="bar"echo ${VAR}

+ echo+ echo foofoo

+ echo

+ VAR=bar+ echo barbar

Page 11: MAN OF BASH #ssmjp 2013.09.25

${parameter:=word}デフォルト値を代入する。wordに指定した値がデフォルト値になる。

parameter に値が代入されていれば、その値が使われる。

parameter になにも代入されていなければ、デフォルト値が使われる。

parameter に word は代入される。

Page 12: MAN OF BASH #ssmjp 2013.09.25

${parameter:=word}#!/bin/bash -x

echo ${VAR}echo ${VAR:="foo"}

echo ${VAR}

VAR="bar"echo ${VAR}

+ echo+ echo foofoo

+ echo foofoo

+ VAR=bar+ echo barbar

Page 13: MAN OF BASH #ssmjp 2013.09.25

使ってみる(スクリプト)

% cat example1.sh

#!/bin/bash -x

PARAM1=${1:-"Default Value"}

echo ${PARAM1}

Page 14: MAN OF BASH #ssmjp 2013.09.25

使ってみる (実行結果)% ./example1.sh

+ PARAM1='Default Value'

+ echo Default Value

Default Value

% ./example1.sh "foo bar"

+ PARAM1='foo bar'

+ echo foo bar

foo bar

Page 15: MAN OF BASH #ssmjp 2013.09.25

${parameter:?word}

値が代入されていなければ、エラーになってスクリプトがそこで終了する。このとき word に指定した文が出力される。

リターンコードは1でした。

Page 16: MAN OF BASH #ssmjp 2013.09.25

${parameter:?word}#!/bin/bash -x

VAR="ABC"

echo ${VAR:?"error."}

+ VAR=ABC

+ echo ABC

ABC

Page 17: MAN OF BASH #ssmjp 2013.09.25

${parameter:?word}#!/bin/bash -x

VAR=""

echo ${VAR:?"error."}

+ VAR=

./example4.sh: line 4: VAR: error.

Page 18: MAN OF BASH #ssmjp 2013.09.25

使ってみる(スクリプト)

% cat ./example2.sh

#!/bin/bash -x

PARAM1=${1:?"何か引数を指定してよ"}

echo ${PARAM1}

Page 19: MAN OF BASH #ssmjp 2013.09.25

使ってみる (実行結果)% ./example2.sh "foo bar"

+ PARAM1='foo bar'

+ echo foo bar

foo bar

% ./example2.sh

./example2.sh: line 2: 1: 何か引数を指定してよ

% echo $?

1

Page 20: MAN OF BASH #ssmjp 2013.09.25

${parameter:+word}Use Alternate Value.word に指定した値が Alternate Value になる。

parameter に値が代入されていれば、Alternate Value が使われる。

parameter になにも代入されていなければ、からっぽのまま。

parameter に word は代入されない。

Page 21: MAN OF BASH #ssmjp 2013.09.25

${parameter:+word}#!/bin/bash -x

VAR="foo"

echo ${VAR}

echo ${VAR:+"bar"}

echo ${VAR}

+ VAR=foo

+ echo foo

foo

+ echo bar

bar

+ echo foo

Page 22: MAN OF BASH #ssmjp 2013.09.25

${parameter:+word}#!/bin/bash -x

echo ${VAR}

echo ${VAR:+"bar"}

VAR="foo"

echo ${VAR}

+ echo

+ echo

+ VAR=foo

+ echo foo

foo

Page 23: MAN OF BASH #ssmjp 2013.09.25

${parameter:offset}${parameter:offset:length}

offset から{末尾まで,lengthだけ}切り出す。

parameter の値は変更されない。

offset のカウントは0から始まる。

offset が文字列長より大きいとからっぽになる。

offset に負の値を指定するとスルーされる。

Page 24: MAN OF BASH #ssmjp 2013.09.25

${parameter:offset}

#!/bin/bash -x

VAR="1234"

echo ${VAR:2}

+ VAR=1234

+ echo 34

34

Page 25: MAN OF BASH #ssmjp 2013.09.25

${parameter:offset:length}

#!/bin/bash -x

VAR="1234"

echo ${VAR:1:2}

+ VAR=1234

+ echo 23

23

Page 26: MAN OF BASH #ssmjp 2013.09.25

${parameter:offset:length}

#!/bin/bash -x

VAR="にほんご"

echo ${VAR:1:2}

+ VAR=$'?\201??\201??\202\223?\201\224'

+ echo $'?\201??\202\223'

ほん

Page 27: MAN OF BASH #ssmjp 2013.09.25

${parameter:offset} はecho ${VAR} | cut -c N- を置き換えられる。

${parameter:offset:length} はecho ${VAR} | cut -c N-M を置き換えられる。

${parameter:offset}${parameter:offset:length}

Page 28: MAN OF BASH #ssmjp 2013.09.25

${parameter:offset}

#!/bin/bash -x

VAR="01234567"

echo ${VAR:4}

echo ${VAR} | cut -c 5-

+ VAR=01234567

+ echo 4567

4567

+ echo 01234567

+ cut -c 5-

4567

Page 29: MAN OF BASH #ssmjp 2013.09.25

${parameter:offset:length}

#!/bin/bash -x

VAR="01234567"

echo ${VAR:2:2}

echo ${VAR} | cut -c 3-4

+ VAR=01234567

+ echo 23

23

+ echo 01234567

+ cut -c 3-4

23

Page 30: MAN OF BASH #ssmjp 2013.09.25

${#parameter}

parameterに代入されている値の長さが返される。

Page 31: MAN OF BASH #ssmjp 2013.09.25

${#parameter}#!/bin/bash -x

VAR_E="English"echo ${#VAR_E}

VAR_J="にほんご"echo ${#VAR_J}

+ VAR_E=English+ echo 77

+ VAR_J=$'?\201??\201??\202\223?\201\224'+ echo 44

Page 32: MAN OF BASH #ssmjp 2013.09.25

スクリプト

#!/bin/bash -xVAR="0123456789"echo ${VAR:$((${#VAR} - 5)):2}

実行結果

+ VAR=0123456789+ echo 5656

入れ子もOK!

楽しくなってくるけどやり過ぎに注意。

Page 33: MAN OF BASH #ssmjp 2013.09.25

${VAR:$((${#VAR}-5)):2}${#VAR} → VAR の長さ = 10$((${#VAR} - 5)) = 10 - 5 = 5${VAR:$((${#VAR} - 5)):2} = ${VAR:5:2}

VAR=”01234567890”

offset 5 の位置の文字は、5。そこから length=2 で、 56 が切り出される。

ご利用は計画的に。

Page 34: MAN OF BASH #ssmjp 2013.09.25

${parameter#word}${parameter%word}parameter の{先頭,末尾}でwordにマッチした部分を削除した値を返す。

# → 先頭

% → 末尾

Page 35: MAN OF BASH #ssmjp 2013.09.25

${parameter#word}#!/bin/bash -x

VAR="0123456789"

echo ${VAR#012}

+ VAR=0123456789

+ echo 3456789

3456789

Page 36: MAN OF BASH #ssmjp 2013.09.25

${parameter%word}#!/bin/bash -x

VAR="0123456789"

echo ${VAR%789}

+ VAR=0123456789

+ echo 0123456

0123456

Page 37: MAN OF BASH #ssmjp 2013.09.25

合わせ技は失敗#!/bin/bash -x

VAR="0123456789"

echo ${VAR#123%789}

+ VAR=0123456789

+ echo 0123456789

0123456789

Page 38: MAN OF BASH #ssmjp 2013.09.25

リベンジ・・・失敗。#!/bin/bash -x

VAR="0123%789456789"

echo ${VAR#123%789}

+ VAR=0123%789456789

+ echo 0123%7894567890123%789456789

Page 39: MAN OF BASH #ssmjp 2013.09.25

実は・・・

${parameter##word}

${parameter%%word}

もあるんだけど・・・・

正直、違いが分かりませんでした。教えてエライ人。

Page 40: MAN OF BASH #ssmjp 2013.09.25

${parameter#word} , ${parameter%word}

manによれば、この二つは、shortest match

${parameter##word} , ${parameter%%word}

manによれば、 この二つは、longest match

何となく意味は分かるような、でも違いがハッキリ分かる例を作れませんでした。

Page 41: MAN OF BASH #ssmjp 2013.09.25

parameter のうち pattern に最初にマッチした部分を string に置き換える。

${parameter/pattern/string}

Page 42: MAN OF BASH #ssmjp 2013.09.25

${parameter/pattern/string}

#!/bin/bash -x

VAR="ABCDEFG"

echo ${VAR/ABC/abc}

+ VAR=ABCDEFG

+ echo abcDEFG

abcDEFG

Page 43: MAN OF BASH #ssmjp 2013.09.25

${parameter/pattern/string}

pattern が # ではじまると、 parameter の先頭でマッチしたとき string に置き換えられる。

Page 44: MAN OF BASH #ssmjp 2013.09.25

${parameter/pattern/string}#!/bin/bash -x

VAR="ABCDEFG"

echo ${VAR/#ABC/abc}

echo ${VAR/#DEF/def}

echo ${VAR/DEF/def}

+ VAR=ABCDEFG

+ echo abcDEFG

abcDEFG

+ echo ABCDEFG

ABCDEFG

+ echo ABCdefG

ABCdefG

Page 45: MAN OF BASH #ssmjp 2013.09.25

${parameter/pattern/string}

pattern が % ではじまると、 parameter の末尾でマッチしたとき string に置き換えられる。

Page 46: MAN OF BASH #ssmjp 2013.09.25

${parameter/pattern/string}#!/bin/bash -x

VAR="ABCDEFG"

echo ${VAR/%EFG/efg}

echo ${VAR/%DEF/def}

echo ${VAR/DEF/def}

+ VAR=ABCDEFG

+ echo ABCDefg

ABCDefg

+ echo ABCDEFG

ABCDEFG

+ echo ABCdefG

ABCdefG

Page 47: MAN OF BASH #ssmjp 2013.09.25

${parameter/pattern/string}

string が空っぽだと、parameter のうちpattern にマッチした部分が削除される。

Page 48: MAN OF BASH #ssmjp 2013.09.25

${parameter/pattern/string}#!/bin/bash -x

VAR="ABCDEFG"

echo ${VAR/DEF}

echo ${VAR/DEF/}

+ VAR=ABCDEFG

+ echo ABCG

ABCG

+ echo ABCG

ABCG

Page 49: MAN OF BASH #ssmjp 2013.09.25

${parameter/pattern/string}

parameter のうち pattern に最初にマッチした部分を string に置き換える。

つまり、pattern に複数箇所マッチしても、置き換えられるのは最初の1回だけ。

Page 50: MAN OF BASH #ssmjp 2013.09.25

${parameter/pattern/string}#!/bin/bash -x

VAR="ABCABC"

echo ${VAR/AB/ab}

+ VAR=ABCABC

+ echo abCABC

abCABC

Page 51: MAN OF BASH #ssmjp 2013.09.25

${parameter/pattern/string}

patternの大文字・小文字は区別される。

Page 52: MAN OF BASH #ssmjp 2013.09.25

${parameter/pattern/string}#!/bin/bash -x

VAR="abCABC"

echo ${VAR/AB/XY}

+ VAR=abCABC

+ echo abCXYC

abCXYC

Page 53: MAN OF BASH #ssmjp 2013.09.25

${parameter/pattern/string}

pattern に . (ドット、ピリオド)を指定しても任意の1文字にはならない

Page 54: MAN OF BASH #ssmjp 2013.09.25

${parameter/pattern/string}#!/bin/bash -x

VAR="ABCD"

echo ${VAR/./Z}

+ VAR=ABCD

+ echo ABCD

ABCD

Page 55: MAN OF BASH #ssmjp 2013.09.25

${parameter/pattern/string}

pattern に ? を指定すると任意の1文字になる。

Page 56: MAN OF BASH #ssmjp 2013.09.25

${parameter/pattern/string}#!/bin/bash -x

VAR="ABCD"

echo ${VAR/?/Z}

echo ${VAR/??/XY}

+ VAR=ABCD

+ echo ZBCD

ZBCD

+ echo XYCD

XYCD

Page 57: MAN OF BASH #ssmjp 2013.09.25

${parameter/pattern/string}

pattern に * を指定すると何でもマッチする。

Page 58: MAN OF BASH #ssmjp 2013.09.25

${parameter/pattern/string}#!/bin/bash -x

VAR="ABCD"

echo ${VAR/*/XYZ}

echo ${VAR/A*/XYZ}

echo ${VAR/B*/XYZ}

+ VAR=ABCD

+ echo XYZ

XYZ

+ echo XYZ

XYZ

+ echo AXYZ

AXYZ

Page 59: MAN OF BASH #ssmjp 2013.09.25

${parameter/pattern/string}

pattern に [ABC] [1-9] なんかもいけた。

Page 60: MAN OF BASH #ssmjp 2013.09.25

${parameter/pattern/string}#!/bin/bash -x

VAR="ABCD"

echo ${VAR/[BC]/X}

+ VAR=ABCD

+ echo AXCD

AXCD

Page 61: MAN OF BASH #ssmjp 2013.09.25

${parameter/pattern/string}#!/bin/bash -x

VAR="0123"

echo ${VAR/[1-4]/X}

+ VAR=0123

+ echo 0X23

0X23

Page 62: MAN OF BASH #ssmjp 2013.09.25

僕は力尽きました

しかし、変数展開だけでみてもまだ手を出せてない機能があります。

配列関連の機能とか

“変数名”に展開する機能とか

Page 63: MAN OF BASH #ssmjp 2013.09.25

いつか踏み込んでみたいです。

Page 64: MAN OF BASH #ssmjp 2013.09.25

おしまい。ご静聴ありがとうございました。