Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
[CAEC MeetUp#4] Go言語におけるos/execパッケージの豆知識
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Bo0km4n
January 28, 2019
Programming
200
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
[CAEC MeetUp#4] Go言語におけるos/execパッケージの豆知識
Bo0km4n
January 28, 2019
More Decks by Bo0km4n
See All by Bo0km4n
Kubernetes Casual Talk: Custom Controller in CyberAgent
bo0km4n
2
470
CA 1day Youth Bootcamp CIU Kubernetes
bo0km4n
2
1.5k
VictoriaMetrics+Prometheusで構築する複数Kubernetesの監視基盤
bo0km4n
4
3.5k
Study Golang by developing mini crawler
bo0km4n
0
120
Other Decks in Programming
See All in Programming
GDG Korea Android: 2026 I/O Extended ~ What's new in Android development tools
pluu
0
100
ビデオ通話が繋がる0.2秒で何が起きているのか
supurazako
2
150
共通化で考えるべきは、実装より公開する型だった
codeegg
0
270
Go言語とトイモデルで学ぶTransformerの気持ち / fukuokago23-transformer
monochromegane
0
140
Embedded SREと共に達成した会員管理システムのAWS移行 - SRE NEXT 2026 ランチスポンサーセッション
niftycorp
PRO
1
2.9k
なぜ型を書くのか? TSKaigi2026で改めて考える #tskaigi_smarthr
kajitack
0
400
jsmini JavaScript Engine を作ってみた話
yosuke_furukawa
PRO
0
180
act1-costs.pdf
sumedhbala
0
240
AI時代のPHPer生存戦略 ~「言語、もうなんでもよくない?」に本気で向き合う~
vivion
0
150
【やさしく解説 設計編・中級 #4】ルールの寿命と、システムの年輪
panda728
PRO
2
160
JAWS-UG横浜 #102 AWSサ終供養LT会 成仏できない AWS サービスたち 〜本日、三体供養します〜
maroon1st
0
220
Claude Opus 4.6以後の受託開発エンジニアの変化(Claude Code開発ノウハウ大公開スペシャルbyクラスメソッド)
iidatakuma
1
840
Featured
See All Featured
How To Speak Unicorn (iThemes Webinar)
marktimemedia
1
510
Reflections from 52 weeks, 52 projects
jeffersonlam
356
21k
Documentation Writing (for coders)
carmenintech
77
5.4k
Are puppies a ranking factor?
jonoalderson
1
3.7k
Navigating Team Friction
lara
192
16k
Mind Mapping
helmedeiros
PRO
1
290
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
Docker and Python
trallard
47
4k
Money Talks: Using Revenue to Get Sh*t Done
nikkihalliwell
0
410
Writing Fast Ruby
sferik
630
63k
Avoiding the “Bad Training, Faster” Trap in the Age of AI
tmiket
0
200
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
37
6.5k
Transcript
Goͷos/execύοέʔδʹ͓͚Δ౾ࣝ CAEC MeetUp #4 (1/28)
2 About Me @KKawabe108 Software Engineer • ෦ উ •
ࣳӜۀେֶେֶӃ ిؾిࢠใֶઐ߈M1 • όΠτઌ: ͳ͠ • ڵຯ: OS, ࢄγεςϜ, ݴޠॲཧܥ • ͋ͱΫϥυपΓશൠ • ࠷ۙ࡞ͬͨͷ: ࢄKVS(raft), ΠϯλϓϦλ
Goݴޠʹ͍ͭͯ About Go which is programming language 01 03 02
Google͕։ൃͨ͠ίϯύΠϧܕݴޠ(Ken ThompsonRob PikeΒ͕ઃܭͨ͠) ੩తͳܕ͚Λߦ͏ݴޠͰڊେͳγεςϜͰ։ൃతʹ, ύϑΥʔϚϯεతʹεέʔϧ͢Δ. GoroutineΛ࢝Ίͱͨܰ͠ྔͳฒྻॲཧػߏΛαϙʔτ͢Δ ϝδϟʔͳΤσΟλͰ΄΅ϑΥʔϚολ͕αϙʔτ͞Ε͍ͯΔͷͰଞਓͷίʔυ͕ඇৗʹ ಡΈ͍͢ɹ<= ݸਓతʹܹਪ͠ϙΠϯτ
ύοέʔδʹ͍ͭͯ About Go which is programming language • ϓϩάϥϜͷ໊લۭؒΛ͚ΔͨΊͷΈ •
ಛఆͷॲཧΛύοέʔδʹΓ͚Δ͜ͱͰӅṭԽΛߦ͏ • େମଞͷݴޠͷϥΠϒϥϦύοέʔδػߏͱಉ͡ײ֮Ͱ͑Δ
os/exec ύοέʔδ About os/exec package GoͰ֎෦ίϚϯυΛ࣮ߦ͢Δࡍʹ͏. ࣮ࡍʹGoͷϥϯλΠϜ͕goroutineΛ ͍, Α͠ͳʹผϓϩηεͷڍಈΛཧ ͯ͘͠ΕΔ.
1 package main 2 3 import ( 4 "os/exec" 5 ) 6 7 func main() { 8 cmd := exec.Command("ls", "-la") 9 if err := cmd.Run(); err != nil { 10 panic(err) 11 } 12 }
͋Δ, ༡ΜͰ͍Δͱ One day, I had be coding… 1 #include<stdio.h>
2 #include<stdlib.h> 3 #include<unistd.h> 4 #include <sys/types.h> 5 #include <sys/stat.h> 6 #include <fcntl.h> 7 8 int main(){ 9 int result = write(0, "hello", 6); 10 if(result == -1){ 11 perror("write"); 12 exit(1); 13 } 14 printf("\nresult = %d", result); 15 return 0; 16 } ඪ४ೖྗʹhelloͱwriteγεςϜίʔϧ Ͱॻ͖ࠐΉ͚ͩͷίʔυ $ gcc sample.c -o sample $ ./sample hello result = 6%
os/execܦ༝Ͱ࣮ߦ͠Α͏ͱ͢Δͱ Try execute binary via os/exec. $ go run sample_exec.go
2019/01/21 11:01:30 exit status 1 exit status 1 Why??? 1 package main 2 3 import ( 4 "log" 5 "os/exec" 6 ) 7 8 func main() { 9 cmd := exec.Command("./sample") 10 if err := cmd.Run(); err != nil { 11 log.Fatal(err) 12 } 13 }
8 όΠφϦͷ ͳͷ͔ ࣮ߦݖݶपΓ ͳͷ͔৭ʑௐ͚ͨͲ݁ہղܾ͠ͳ͔ͬͨ
9 TwitterͰฉ͍ͯΈͨ Help me twitter.
10 exec.Cmdߏମ exchange stdin ͔֬ʹexec.CommandͷฦΓͰ͋Δexec.Cmdߏମඪ४ೖྗͷϝϯόΛ࣋ͬͯΔ
11 exec.Cmdͷ࣋ͭ, stdinΛૠ͛ସ͑Δ exchange stdin 1 func main() { 2
cmd := exec.Command("./sample") 3 cmd.Stdin = os.Stdin 4 _, err := cmd.Output() 5 if err != nil { 6 log.Fatal(err) 7 } 8 } 1 $ go run sample_exec.go 2 hello 1 package main 2 3 import ( 4 "log" 5 "os/exec" 6 ) 7 8 func main() { 9 cmd := exec.Command("./sample") 10 if err := cmd.Run(); err != nil { 11 log.Fatal(err) 12 } 13 } OutputؔRunͯ͠ ඪ४ग़ྗʹॻ͖ࠐ·Εͨ݁Ռऔಘ͢Δ
12 ্ख͍ͬͨ͘!!! Ͱ, ԿͰϓϩηεͷඪ४ೖྗΛม͑Δͱ্ख͘ߦ͘ͷʁ
13 exec.CmdपΓͷίʔυΛͬͯΈΔ investigate exec.Cmd codes.
14 Let’s go 1 func (c *Cmd) Output() ([]byte, error)
{ 2 if c.Stdout != nil { 3 return nil, errors.New("exec: Stdout already set") 4 } 5 var stdout bytes.Buffer 6 c.Stdout = &stdout 7 8 captureErr := c.Stderr == nil 9 if captureErr { 10 c.Stderr = &prefixSuffixSaver{N: 32 << 10} 11 } 12 13 err := c.Run() 14 if err != nil && captureErr { 15 if ee, ok := err.(*ExitError); ok { 16 ee.Stderr = c.Stderr.(*prefixSuffixSaver).Bytes() 17 } 18 } 19 return stdout.Bytes(), err 20 } 1 func (c *Cmd) Run() error { 2 if err := c.Start(); err != nil { 3 return err 4 } 5 return c.Wait() 6 } ݁ہStartΛݺΜͰΔͷͰStartΛಡ͏ Cmdߏମͷඪ४ೖྗॳظԽ෦Λ୳͢ StdoutͱStderrʹؔͯ͠ॳظԽ͍ͯ͠Δ
15 Cmdߏମͷඪ४ೖྗॳظԽ෦Λ୳͢ Let’s go 1 func (c *Cmd) Start() error
{ 2 3 ... 4 5 type F func(*Cmd) (*os.File, error) 6 for _, setupFd := range []F{(*Cmd).stdin, (*Cmd).stdout, (*Cmd).stderr} { 7 fd, err := setupFd(c) 8 if err != nil { 9 c.closeDescriptors(c.closeAfterStart) 10 c.closeDescriptors(c.closeAfterWait) 11 return err 12 } 13 c.childFiles = append(c.childFiles, fd) 14 } 15 c.childFiles = append(c.childFiles, c.ExtraFiles...) 16 17 ... 18 19 } ඪ४ೖྗͷॳظԽͬΆ͍ॲཧΛݟ͚ͭͨ Cmdߏମʹඥͮ͘stdinͱ͍͏ ؔϙΠϯλ
16 Cmdߏମͷඪ४ೖྗॳظԽ෦Λ୳͢ Let’s go 1 func (c *Cmd) stdin() (f
*os.File, err error) { 2 if c.Stdin == nil { 3 f, err = os.Open(os.DevNull) 4 if err != nil { 5 return 6 } 7 c.closeAfterStart = append(c.closeAfterStart, f) 8 return 9 } 10 11 if f, ok := c.Stdin.(*os.File); ok { 12 return f, nil 13 } 14 15 pr, pw, err := os.Pipe() 16 if err != nil { 17 return 18 } /dev/nullΛopenͯ͠ඪ४ೖྗ ʹׂΓ͍ͯͯΔʂ ͋ΕʁͰ/dev/null writeγεςϜίʔϧͰ ॻ͖ࠐΊΔͣ ౾ࣝ: goฦΓʹ໊લΛ͚ͭΔ ͜ͱ͕Ͱ͖, return͢ΔͱσϑΥϧ τͰͦͷ໊લͷมΛฦ͢
17 1 2 func main() { 3 devNull, _ :=
os.Open("/dev/null") 4 b, err := syscall.Write(int(devNull.Fd()), []byte("hello")) 5 if err != nil { 6 log.Fatal(err) 7 } 8 fmt.Println(b) 9 } ࣅͨΑ͏ͳίʔυͰ࣮ݧͯ͠ΈΔ experiment 1 go run sample_devnull.go 2 2019/01/21 13:56:03 bad file descriptor 3 exit status 1
18 Error: Bad file descriptor experiment ϑΝΠϧσΟεΫϦϓλʹ ॻ͖ࠐΈݖݶ͕༩͞Εͯͳ͍
19 os.OpenͷgodocΛಡΜͰΈΔͱɾɾɾ read GoDoc Read OnlyͰ։͍ͯΔ͔Βॻ͖ࠐΊͳ͔ͬͨʂʂʂ
20 ·ͱΊ conclusion • Goͷos.execύοέʔδ֎෦ίϚϯυΛ࣮ߦ͢Δࡍ, σϑΥϧτͰඪ४ೖྗΛ/dev/nullʹઃఆ͢Δ • ͜ͷ࣌, Read OnlyͳͷͰॻ͖ࠐΈͰ͖ͳ͍
• ॻ͖ࠐΈ͍ͨ࣌cmd.Stdinʹॻ͖ࠐΈݖݶΛ༩ͨ͠σΟεΫϦϓλΛઃఆ͠Α͏
Thank you for listening! Let’s fun programming with go!