Ruby ã§ã·ã§ã«ã®ãããªãã®ãä½ã£ã¦ã¿ãã¨ãRuby ã¨ã·ã§ã«ãã·ã¹ãã ã³ã¼ã«ã®ç解ãã§ãã¦ãç ä¿®ã®èª²é¡ã¨ãã«ããããããªããã¨10å¹´ãããåã«æã£ã¦ãã®ãããµã¨æãåºããã®ã§æ¸ãã¦ã¿ã¾ãã
åºæ¬
ã·ã§ã«ã®åä½ãç°¡åã«èª¬æããã¨æ¬¡ã®ãããªæãã§ãã
- ããã³ãããåºå
- æ¨æºå ¥åããã³ãã³ãã©ã¤ã³ãèªã¿è¾¼ã
- èªã¿è¾¼ãã ã³ãã³ããå®è¡ãã
- ã³ãã³ãã®çµäºãå¾ ã¤
- 1 ã«æ»ã
ããããã®ã¾ã¾ Ruby ã§æ¸ãã¦ã¿ã¾ãã
while true print '-> ' # ããã³ãã表示 cmd = gets or break # ã³ãã³ãå ¥å cmd.chomp! # æ«å°¾ã®æ¹è¡åé¤ pid = Process.fork do # åããã»ã¹çæ Process.exec [cmd, cmd] # ã³ãã³ãå®è¡ end Process.waitall # åããã»ã¹ã®çµäºå¾ ã¡ end
Process.exec
ã®å¼æ°ã« cmd
ã§ã¯ãªã [cmd, cmd]
ã渡ãã¦ãã¾ããå¼æ°ãä¸ã¤ã ãã§æååã®å ´å㯠Process.exec
ã¯ã·ã§ã«ãçµç±ããå¯è½æ§ãããããã§ããããããã·ã§ã«ãä½ããã¨ãã¦ããã®ã«ã·ã§ã«çµç±ã§ã³ãã³ããå®è¡ãã¦ãã¾ã£ã¦ã¯é¢ç½ãããªãã¨ããªãã®ã§ãã·ã§ã«ãçµç±ããªãããã«ãã¦ãã¾ãã
å®è¡ãã¦ã¿ã¾ããä½æããã¹ã¯ãªãã㯠sheru ã¨ãããã¡ã¤ã«åã«ãã¦ããã¾ãã
% ruby sheru -> date 2013å¹´ 10æ 8æ¥ ç«ææ¥ 23:26:03 JST > ls sheru text.md -> â çµäºã¯ Ctrl-D
ãã¾ãåãã¦ããããã§ãã
EOF
ã¡ãªã¿ã« Ctrl-D ã§æ¨æºå ¥åãçµäºããã®ã¯ãã³ãã³ãã Ctrl-D ã®ã³ã¼ããèªã¿è¾¼ãã§ç¹å¥æ±ããã¦ããã®ã§ã¯ãªãã端æ«ã§ Ctrl-D ã EOF(End Of File)ã«å²ãå½ã¦ããã¦ããããã§ãã
stty ã³ãã³ãã§å²ãå½ã¦ã確èªãããã¨ãã§ãã¾ãã
% stty -a speed 38400 baud; rows 24; columns 80; line = 0; intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = M-^?; eol2 = M-^?; swtch = M-^?; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0; -parenb -parodd cs8 hupcl -cstopb cread -clocal -crtscts -ignbrk brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc ixany imaxbel iutf8 opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0 isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke
stty ã³ãã³ãã®åºåã®2è¡ç®ã® eof = ^D
ã¨ããã®ãããã§ããã¡ãªã¿ã« Cntrl-C ã§ã³ãã³ããä¸æããã®ã intr = ^C
ãè¨å®ããã¦ããããã§ãã
Ctrl-D 以å¤ã®ãã¼ãå²ãå½ã¦ã¦ã¿ã¾ãããã
% stty eof ^X % stty -a speed 38400 baud; rows 24; columns 80; line = 0; intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^X; eol = M-^?; eol2 = M-^?; ...
Ctrl-X ãå²ãå½ã¦ã¦ã¿ã¾ããããã以éãã®ç«¯æ«ã§ã¯ Ctrl-X ã§å ¥åãçµäºããããã«ãªãã¾ããä»ã®ç«¯æ«ã«ã¯å½±é¿ãã¾ããã
% ruby sheru -> ^D â Ctrl-D ãå ¥åãã¦ãæ®éã®æåã¨ãã¦æ±ããã -> â çµäºããã«ã¯ Ctrl-X ãå ¥å
ãããããã®ã§å ã«æ»ãã¦ããã¾ãã
% stty eof ^D
ã³ãã³ãã©ã¤ã³ã®ãã¼ã¹
å ¥åãå ã«ã³ãã³ããã¡ããã¨åãããã¨ãã§ãã¾ãããã¨ãããã³ãã³ãã«å¼æ°ãæå®ããã¨ã¨ã©ã¼ã«ãªã£ã¦ãã¾ãã¾ãã
% ruby sheru -> ls -l ./sheru:7:in `exec': No such file or directory - ls -l (Errno::ENOENT) from ./sheru:7:in `block in <main>' from ./sheru:6:in `fork' from ./sheru:6:in `<main>' ->
å¼æ°ã¤ãã® ls
ã³ãã³ãã§ã¯ãªããls -l
ã¨ããã³ãã³ããæ¢ãã¦ããã®ãããªã³ãã³ãã¯ç¡ãã®ã§ã¨ã©ã¼ã«ãªã£ã¦ãã¾ãã
å
¥åæååãã³ãã³ãã¨å¼æ°ã«å解ã㦠exec
ã«æ¸¡ãå¿
è¦ãããã¾ãã
ã·ã§ã«ã®è¡ã®ãã¼ã¹ã¯å®ã¯ããããè¤éãªã®ã§ãããããã§ã¯åç´ã«ç©ºç½ã§åºåãã ãã«ãã¦ããã¾ãã
while true print '-> ' # ããã³ãã表示 line = gets or break # ã³ãã³ãå ¥å line.chomp! # æ«å°¾ã®æ¹è¡åé¤ cmd, *args = line.split(/\s+/) # 空ç½ã§å ¥åãåºåã pid = Process.fork do # åããã»ã¹çæ Process.exec [cmd, cmd], *args # ã³ãã³ãå®è¡ end Process.waitall # åããã»ã¹ã®çµäºå¾ ã¡ end
% ruby sheru -> ls -l åè¨ 8 -rwxr-xr-x 1 tommy tommy 472 10æ 8 23:36 sheru -rwxr-xr-x 1 tommy tommy 472 10æ 8 23:36 text.md ->
ã¡ããã¨å¼æ°ãæ±ããã¨ãã§ãã¾ããã
ã¯ã¤ã«ãã«ã¼ã
ãã¡ã¤ã«åã«ã¯ã¤ã«ãã«ã¼ãã使ã£ã¦ã¿ã¾ãããã
% ruby sheru -> ls * ls: * ã«ã¢ã¯ã»ã¹ã§ãã¾ãã: ãã®ãããªãã¡ã¤ã«ããã£ã¬ã¯ããªã¯ããã¾ãã ->
ls
ã³ãã³ãã *
ããã®ã¾ã¾ãã¡ã¤ã«åã¨ãã¦æ±ã£ã¦ãã¾ã£ã¦ããã¡ã¤ã«ããªãã¨è¨ã£ã¦ã¾ãã
ã¯ã¤ã«ãã«ã¼ãããã¡ã¤ã«åã«å±éãã¦ããã®ã¯åã³ãã³ãã§ã¯ãªããã·ã§ã«ã®å½¹å²ãªã®ã§ãã
ã·ã§ã«ã®ã¯ã¤ã«ãã«ã¼ããããããããã¾ãããç°¡åã®ããã«ããã§ã¯ *
ã®ä¸æåã ããã¯ã¤ã«ãã«ã¼ãã¨ãã¦æ±ããã¨ã«ãã¾ãã
def parse_line(line) line.split(/\s+/).map{|arg| if arg == '*' # å¼æ°ã '*' ã®å ´å㯠Dir.glob('*') # ãã¡ã¤ã«åã«å±éãã else arg end }.flatten # '*' ã®å±éãé åã«ãªã£ã¦ããã®ã§ãã©ããå end while true print '-> ' # ããã³ãã表示 line = gets or break # ã³ãã³ãå ¥å line.chomp! # æ«å°¾ã®æ¹è¡åé¤ cmd, *args = parse_line line # å ¥åã®ãã¼ã¹ pid = Process.fork do # åããã»ã¹çæ Process.exec [cmd, cmd], *args # ã³ãã³ãå®è¡ end Process.waitall # åããã»ã¹ã®çµäºå¾ ã¡ end
ã³ãã³ãã©ã¤ã³ã®ãã¼ã¹å¦çãè¤éã«ãªã£ã¦ããã®ã§ã¡ã½ãããåãã¾ããã
% ruby sheru -> ls * sheru text.md ->
ãªãã¤ã¬ã¯ã
æ¨æºå ¥åãæ¨æºåºåãæ¨æºã¨ã©ã¼åºåã¯ãããããããã»ã¹ã®ãã¡ã¤ã«è¨è¿°å 0, 1, 2 ã«ã¤ããããååã§ãã 端æ«ããå®è¡ãããå ´åã¯é常ã¯ãããã端æ«ã«çµã³ä»ãããã¦ãã¾ãã ãªã®ã§ã端æ«ããå ¥åãããæåãã³ãã³ãã®æ¨æºå ¥åããèªã¿è¾¼ã¾ããã³ãã³ãã®æ¨æºåºåã«æ¸ããããã¼ã¿ã¯ç«¯æ«ã«åºåãããã®ã§ãã
ä¸è¬çãªã·ã§ã«ã¯ >
ã§æ¨æºåºåããã¡ã¤ã«ã«æ¸ãåºããã¨ãã§ãã¾ãããããå®è£
ãã¦ã¿ã¾ãããã
ç°¡åã®ããã« >filename
ã®å½¢å¼ã ãããµãã¼ããã¾ãã>
ã®å¾ã«ç©ºç½æåã¯è¦ãã¾ããã
def parse_line(line) @stdout = nil # æ¨æºåºåãªãã¤ã¬ã¯ãå line.split(/\s+/).map{|arg| if arg == '*' # å¼æ°ã '*' ã®å ´å㯠Dir.glob('*') # ãã¡ã¤ã«åã«å±éãã elsif arg =~ /\A>(.*)/ # å¼æ°ã '>' ã§å§ã¾ãå ´å㯠@stdout = $1 # ç¶ãæååããªãã¤ã¬ã¯ããã¡ã¤ã«åã¨ãã nil # ãã®å¼æ°ã¯ç¡è¦ else arg end }.compact.flatten # '*' ã®å±éãé åã«ãªã£ã¦ããã®ã§ãã©ããå end while true print '-> ' # ããã³ãã表示 line = gets or break # ã³ãã³ãå ¥å line.chomp! # æ«å°¾ã®æ¹è¡åé¤ cmd, *args = parse_line line # å ¥åã®ãã¼ã¹ pid = Process.fork do # åããã»ã¹çæ if @stdout # ãªãã¤ã¬ã¯ãå ãæå®ããã¦ããå ´å㯠STDOUT.reopen(@stdout, 'w') # æ¨æºåºåããã¡ã¤ã«ã«å¤æ´ end Process.exec [cmd, cmd], *args # ã³ãã³ãå®è¡ end Process.waitall # åããã»ã¹ã®çµäºå¾ ã¡ end
ãªãã¤ã¬ã¯ãã«ã¯ $stdout
ã§ã¯ãªã STDOUT
ã使ç¨ãã¾ãã
$stdout
㯠Ruby ã®ã¡ã½ããã§ããæå¹ã§ã¯ããã¾ãããæ¨æºåºå(=ãã¡ã¤ã«è¨è¿°å1çª)ã®ãã¡ã¤ã«ãå¤æ´ããã«ã¯ STDOUT ãå¤æ´ããå¿
è¦ãããã¾ãã
ãªããRuby ã® exec
ã«ã¯ãããç°¡åã«è¡ãæ¹æ³ãç¨æããã¦ãã¦ã次ã®ããã«è¨è¿°ã§ãã¾ãã
Process.exec [cmd, cmd], *args, :out=>@stdout
å®è¡çµæ
% ruby sheru -> ls >/tmp/xxx -> cat /tmp/xxx sheru text.md ->
ãã¤ã
ä¸è¬çãªã·ã§ã«ã¯ãã³ãã³ãã©ã¤ã³ä¸ã« |
ãããã¨ããã®åå¾ã«æ¸ãããäºã¤ã®ããã»ã¹ãåæã«åããã¦ãåã®ããã»ã¹ã®æ¨æºåºåã¨å¾ãã®ããã»ã¹ã®æ¨æºå
¥åãæ¥ç¶ãã¾ãã
pipe ã·ã¹ãã ã³ã¼ã«ã使ç¨ããã¨ï¼ã¤ã®ãã¡ã¤ã«è¨è¿°åãè¿ããã¾ããããããã¤ãã§ãã ãã®ãã¡ã¤ã«è¨è¿°åã¯ãã¡ã¤ã«ã·ã¹ãã ä¸ã®ãã¡ã¤ã«ã«ã¯é¢é£ã¥ãã¦ããªãã®ã§ãã¡ã¤ã«åã¯ããã¾ããã ååç¡ããã¤ãã¨ãå¼ã°ãã¾ãã
ãã¤ãã¯ä¸æ¹ã«æ¸ãè¾¼ãã¨ããçæ¹ããèªã¿è¾¼ããã¨ãã§ãã¾ãããªã®ã§ãä¸ã¤ãåã®ããã»ã¹ã®æ¨æºåºåã«è¨å®ãã¦ãããä¸ã¤ãå¾ãã®ããã»ã¹ã®æ¨æºå ¥åã«è¨å®ãããã¨ã§ããã¤ãå¦çãå®ç¾ã§ãã¾ãã
以ä¸ã®ããã°ã©ã ã§ã¯ãããããããªãã®ã§ãå ã«å®è£ ãããªãã¤ã¬ã¯ãå¦çã¯åé¤ãã¦ãã¾ãã
# [[cmd1, arg, ...], [cmd2, arg, ...], ...] ãè¿ã def parse_line(line) cmd = [] cmds = [cmd] line.split(/\s+/).each do |arg| if arg == '*' # å¼æ°ã '*' ã®å ´å㯠cmd.concat Dir.glob('*') # ãã¡ã¤ã«åã«å±éãã elsif arg == '|' # ãã¤ãã®å ´å㯠cmd = [] # 次ããæ°ããã³ãã³ã cmds.push cmd else cmd.push arg end end cmds end while true print '-> ' # ããã³ãã表示 line = gets or break # ã³ãã³ãå ¥å line.chomp! # æ«å°¾ã®æ¹è¡åé¤ cmds = parse_line line pipes = Array.new(cmds.count-1){IO.pipe} # ã³ãã³ãæ¥ç¶åã®ãã¤ããç¨æ pipes = [nil, pipes.flatten.reverse, nil] # [nil, W, R, W, R, ..., nil] ã«ä¸¦ã³æ¿ã .flatten cmds.each do |cmd, *args| r, w = pipes.shift 2 # ãã¤ããï¼ã¤åãåºã pid = Process.fork do # åããã»ã¹çæ STDIN.reopen r if r # èªã¿è¾¼ã¿ãã¤ãã«ãªãã¤ã¬ã¯ã STDOUT.reopen w if w # æ¸ãè¾¼ã¿ãã¤ãã«ãªãã¤ã¬ã¯ã Process.exec [cmd, cmd], *args # ã³ãã³ãå®è¡ end r.close if r # 親ããã»ã¹ã§ã¯ä¸è¦ãªã®ã§ w.close if w # ãã¤ããã¯ãã¼ãº end Process.waitall # åããã»ã¹ã®çµäºå¾ ã¡ end
å®è¡çµæ
% ruby sheru -> seq 100 | grep 0 | head -3 10 20 30 ->
ãããã«
ã·ã§ã«ã¨å¼ã¶ã«ã¯ãã¢ãããå®è£ ã§ãããã·ã§ã«ãã©ã®ããã«ãã¦ã³ãã³ããå®è¡ãã¦ããã®ãã®ä¾ãããã«ã¯ãªã£ãã®ã§ã¯ãªããã¨æãã¾ãã
ã·ã¹ãã ã³ã¼ã«ã¯ C ã§è¨è¿°ããã¨çµæ§é¢åãªãã¨ãå¤ãã®ã§ãããRuby ã使ãã¨ã¨ã¦ãç°¡åã«è¨è¿°ãããã¨ãã§ãã¾ããRuby ã¯ç´ æ´ãããã§ããã
ã·ã¹ãã ã³ã¼ã«ãRuby ãã使ãæ¹æ³ã«ã¤ãã¦ãã£ã¨è©³ããç¥ããã人ã¯ãããªãã»ã©Unixããã»ã¹ãã¨ããæ¸ç±ããªã¹ã¹ã¡ã§ãã
é人åºçä¼
çºè¡æ¥: 2013-04-25
対å¿ãã©ã¼ããã: EPUB, PDF, ZIP