環境
混乱
$ matsuya | pee cat "grep -o ." rev
んどうーレカニミ
ミニカレーうどん
ミ
ニ
カ
レ
ー
う
ど
ん
- シェルスクリプトって
pee cat "grep -o ." rev
みたいにコマンドを並べられるんだっけ?
- そもそも
pee
を初めて見た。pee
とは?
pee
tee
の出力先がパイプになったコマンド。パイプだからt→pなのかも。
SYNOPSIS
pee [--[no-]ignore-sigpipe] [--[no-]ignore-write-errors] [["command"...]]
tee
はこんな感じで引数に複数のファイルを指定できる。
$ echo foo | tee bar.txt baz.txt
$ cat bar.txt
foo
$ cat baz.txt
foo
- つまり
pee
も引数として複数のコマンドを指定できる...?
$ echo foo | pee cat cat cat
foo
foo
foo
- おお、やはり。
- ということで最初のワンライナーを見返してみる。これは
pee
の引数のコマンドに共通の標準入力を与えているものなのか。
$ matsuya | pee cat "grep -o ." rev
オプション付きコマンドの場合
"grep -o ."
のダブルクォートはもしかするとコマンドにオプションを付けるときに必要なのかも...?
- 試しに下記を実行してみる
$ echo foo | pee cat cat "cat -n"
foo
foo
1 foo
- 最後の
cat
だけ行番号付きで出力された。
- やっぱりコマンドにオプションを指定するときはダブルクォートで囲ってあげる必要があるということみたい。
- 考えてみれば、シェルスクリプトでは半角スペースが引数の区切りとして解釈されてしまうし仕方ない。
出力順
pee
の引数に指定されたコマンドは先頭から順に終了するとは限らない。
- 実際、最初に示した例では
rev
→cat
→ "grep -o ."
の順に標準出力に書き込まれている。
- 何度か試すと時々順序が入れ替わる様子が観察できたので固定の出力が得られることは期待できないみたい。
pee
を親とした子プロセスがforkされて個々のコマンドが並行(コンカレント)に実行されているから...だと思う (違っていたらすまん)