bashで標準入力すべてを得るTIPS
bashで標準入力すべてを得るには
read -rd '' s; echo "$s"
注意しなきゃいけないのはechoで出力する時に「"」をつけ忘れないこと!
つけているときちんと出力するが
$ echo -e "ab\ncde\ndef" | (read -rd '' s; echo "$s") ab cde def
つけ忘れるとechoが改行コードをフィールドセパレータとして解釈してしまう。
$ echo -e "ab\ncde\ndef" | (read -rd '' s; echo $s) ab cde def
標準入力からデータを受け取ってそれをCソースとしてコンパイルし実行するfunctionを定義してみた。
$ function foo(){ d=/tmp/$$_;read -rd '' s; echo "$s">$d.c; gcc $d.c -o $d.out; $d.out; rm $d.{c,out}; } ; echo -e '#include <stdio.h>\nmain(){\nprintf("hello,world\\n");\n}'|foo hello,world
うまくいった。
サブシェルで書くと
$ echo -e '#include <stdio.h>\nmain(){\nprintf("hello,world\\n");\n}' | (d=/tmp/$$_;read -rd '' s; echo "$s">$d.c; gcc $d.c -o $d.out; $d.out; rm $d.{c,out}; ) hello,world
サブシェルすげぇ。rubyのイテレータ(いまはブロック)みたいだ。
実はbashってすごいんじゃないかと思いはじめた今日この頃。
$ echo -e "ab\ncde\ndef" | (read -rd '' s; echo "$s") | cat -n 1 ab 2 cde 3 def
read文の直後にパイプをつなげられたらほんとにかっこいいんだけどな…ってそりゃrubyか。
まあ、「read -rd '' s; echo "$s"」このフレーズがrubyのSTDIN.readと同じ機能を持つって覚えればOK
ほかにもevalとかにも応用可能
$ echo -e 'for i in {1..5}\ndo\necho $i\ndone' | ( read -rd '' s; echo "$s";eval "$s" ) for i in {1..5} do echo $i done 1 2 3 4 5
すげえteeいらず。変数最高!(嘘