シェル芸勉強会 2017-04-02

プロセスまわり

Nohup http://itpro.nikkeibp.co.jp/article/COLUMN/20060227/230850/

Fg http://itpro.nikkeibp.co.jp/article/COLUMN/20060227/230776/

Trap http://shellscript.sunone.me/signal_and_trap.html

Trapコマンドは便利

Exitするときに実行される

trap 'echo goobye' 0

停止(Ctrl + C)のときに実行される(サンプル)

##!/bin/bash -xve

error_exit () {
  #touch ~/tmp/hoge
  echo "hello"
  exit 0
}

trap error_exit 2

touch /tmp/hoeg
sleep 10000

止める

[Ctrl] + Z

止めたもの見る

$ jobs

手前で動かす

$ fg (YourNumber)

後ろで動かす

$ bg (YourNumber)

Perl練習

$ perl -E ' print "hello perl\n" '

$ perl -le '$a=1;print $a'
1
$ perl -le '@a=(1,2,3);print @a'
123
$ perl -le '@a=(1,2,3);print "@a"'
1 2 3

$ perl -le '@a=(1,2,3);print join "+",1,2,3'
1+2+3

$ perl -le '@a=1,2,3;print "@a"'
1

$ perl -le 'while($a++<10){print $a}'
1
2
3
4
5
6
7
8
9
10

$ awk 'BEGIN{while(a++<10)print a}'
1
2
3
4
5
6
7
8
9
10

$ perl -le 'print $a while($a++<10)'
1
2
3
4
5
6
7
8
9
10

{}がperlは必須。後置制御文の場合は不要。

$ awk 'BEGIN{
a=10
b=20
print a+b
}'
30

$ perl -le '$a=10;
$b=20;
print $a+$b'
30

- スカラーコンテキスト
- リストコンテキスト

$ perl -e '@a=(1,1,1);$a=@a;print "$a\n"'
3

- bool型は存在しない
- 偽は「空文字列と文字列の"0"と数値の0」

$ awk 'BEGIN{print 0 ? 1 : 2}'
2
$ perl -le 'print "" ? 1 : 2'
2
$ perl -le 'print 0 ? 1 : 2'
2
$ awk 'BEGIN{print "0" ? 1 : 2}'
1
$ perl -le 'print 0.0 ? 1 : 2'
2

- ダイヤモンド演算子
- 正規表現
- 未定義の変数を使用可能

$ perl -le 'print $a . "123"' # while($a++<10){print $a}'
123

$ perl -le 'print $a ? 1 : 2'
2
$ perl -wle 'print $a ? 1 : 2'
Name "main::a" used only once: possible typo at -e line 1.
2
$ perl -wle '$a="";print $a ? 1 : 2'
2

未定義の変数は間違いのもと

$ perl -le '$abc="123";print $abe'

$ perl -wle '$abc="123";print $abe'
Name "main::abc" used only once: possible typo at -e line 1.
Name "main::abe" used only once: possible typo at -e line 1.
Use of uninitialized value $abe in print at -e line 1.

ダイヤモンド演算子

$ echo aaa > aaa
$ echo bbb > bbb
$
$ echo hello | cat aaa - bbb
aaa
hello
bbb
$

これを真似ると...

$ echo ccc | perl -e '$l=<>;print $l'

$ echo -e "aaa\nbbb\nccc\n" | perl -e 'while($l=<>){print $l}'
aaa
bbb
ccc

$ echo -e "aaa bbb ccc\n" | perl -e 'while($l=<>){print $l}' aaa - bbb
aaa
aaa bbb ccc

bbb

豊富な特殊変数

$.と$_

$ perl -le 'for $a (1,2,3,4){print $a}'
1
2
3
4
$ perl -le 'for (1,2,3,4){print $_}'
1
2
3
4
$ perl -le 'for (1,2,3,4){print}'
1
2
3
4

$ echo ccc | perl -e 'while(<>){print}'
ccc
$ echo ccc | perl -e 'while(<>){print $_}'
ccc
$ echo ccc | perl -e 'while($a=<>){print $a}'
ccc

$ printf 'aaa\nbbb\nxxx\n' | perl -e 'while(<>){print $.,$_}'
1aaa
2bbb
3xxx
$ printf 'aaa\nbbb\nxxx\n' | perl -e 'while(<>){print ($.,$_)}'
1aaa
2bbb
3xxx

$ printf 'aaa\nbbb\nxxx\n' | perl -e 'while(<>){print ($.,$_)}' aaa - bbb
1aaa
2aaa
3bbb
4xxx
5bbb

出力のレコードセパレータを変更
$ printf 'aaa,bbb,ccc,' | perl -e '$/=",";while(<>){print "[$_]"}'
[aaa,][bbb,][ccc,]$

$ printf 'aaa,bbb,ccc,' | perl -e '$/="@";while(<>){print "[$_]"}'
[aaa,bbb,ccc,]$

$ perl -le 'while(<>){print $ARGV}' aaa bbb
aaa
bbb

違う意味をもつ三銃士

- $ARGV
- ARGV
- @ARGV

$ perl -e 'while(<>){print; close ARGV}' aaa
aaaの内容
$ perl -e 'while(<>){print; close ARGV}' aaa bbb
aaaの内容
bbbの中身

特殊な変数

$"と$,

$ perl -le 'print 1,2,3'
123
$ perl -le '$,=","; print 1,2,3'
1,2,3

豊富な起動オプション

-n 読みこみ

-p 読み込んで出力

$ printf 'aaa\nbbb\nccc\n' | perl -en 'print'
$ printf 'aaa\nbbb\nccc\n' | perl -ne 'print'
aaa
bbb
ccc

$ printf 'aaa\nbbb\nccc\n' | perl -pe ''
aaa
bbb
ccc

$ printf 'aaa\nbbb\nccc\n' | perl -pe '' aaa -
aaaの内容
aaa
bbb
ccc

-a フィールド処理
-p

$ printf 'aaa\nbbb\nccc\n' | perl -nae 'print @F'
aaabbbccc$

$ printf 'aaa bbb ccc' | perl -lnae 'print $F[0]'
aaa

`man ascii`でチェック

$ printf 'aaa;bbb;ccc;' | perl -0073 -ne 'print "[$_]"'
[aaa;][bbb;][ccc;]$

$ printf 'aaa\0bbb\0ccc\0' | perl -0 -ne 'print "[$_]"'
[aaa][bbb][ccc]$

$ printf 'aaa\nbbb\nccc\n' | perl -e 'print <>'
aaa
bbb
ccc

シェルスクリプトとかの引数とれる

$ perl -s -le 'print $a' -- -a=123
123

$ perl -le 'use utf8;print "あ"=~/\p{Hiragana}/ ? 1 : 2'
1
$ perl -le 'print "あ"=~/\p{Hiragana}/ ? 1 : 2'
2
$ perl -Mutf8 -le 'print "あ"=~/\p{Hiragana}/ ? 1 : 2'
1
$ echo あ | perl -Mutf8 -lne 'print $_=~/\p{Hiragana}/ ? 1 : 2'
2
$ echo あ | perl -C -Mutf8 -lne 'print $_=~/\p{Hiragana}/ ? 1 : 2'
1

詳しいことは`perldoc perlrun`

Perlの演算子
- マッチ演算子
- 比較演算子

- 文字列=~m/パターン/[修飾子]
- 演算子の対象は$_
- デリミタにはブラケットペアが使用可能

$ perl -le 'print "abc"=~m#.*# ? 1 : 2'
1
$ perl -le 'print "abc"=~m#d# ? 1 : 2'
2
$ perl -le 'print "abc"=~/d/ ? 1 : 2'
2
$ perl -le 'print "abc"=~m<d> ? 1 : 2'
2

置換演算子

- 文字列=~s/パターン/[修飾子]