2013-05-15 15 views
12

Go langでttyのサイズを取得するには?私はstty sizeコマンドを実行してこれを試行していますが、コードを正しく作成できません。Goで端末のサイズを取得

package main 

import (
    "os/exec" 
    "fmt" 
    "log" 
) 

func main() { 
    out, err := exec.Command("stty", "size").Output() 
    fmt.Printf("out: %#v\n", out) 
    fmt.Printf("err: %#v\n", err) 
    if err != nil { 
    log.Fatal(err) 
    } 
} 

出力:

out: []byte{} 
err: &exec.ExitError{ProcessState:(*os.ProcessState)(0xc200066520)} 
2013/05/16 02:35:57 exit status 1 
exit status 1 

私は行くが、それが動作している現在のttyに関係のないプロセスを生成しますので、これはあると思います。サイズを取得するために、現在の端末にコマンドを関連付けるにはどうすればよいですか?

答えて

16

あなたは親のstdinに子プロセスのアクセス権を与える場合、それは動作します:

package main 

import (
    "os/exec" 
    "fmt" 
    "log" 
    "os" 
) 

func main() { 
    cmd := exec.Command("stty", "size") 
    cmd.Stdin = os.Stdin 
    out, err := cmd.Output() 
    fmt.Printf("out: %#v\n", string(out)) 
    fmt.Printf("err: %#v\n", err) 
    if err != nil { 
    log.Fatal(err) 
    } 
} 

収量:

out: "36 118\n" 
err: <nil> 
+0

これらの行を関数に入れて、関数をテストするために 'testing'モジュールでユニットテストを設定すると、常に空の配列が得られることがわかります。 – Kingname

14

私は同様の問題に引っかかったの。ここで私は結局何をしたのですか?

サブプロセスを使用しないため、場合によっては望ましい場合もあります。

import (
    "syscall" 
    "unsafe" 
) 

type winsize struct { 
    Row uint16 
    Col uint16 
    Xpixel uint16 
    Ypixel uint16 
} 

func getWidth() uint { 
    ws := &winsize{} 
    retCode, _, errno := syscall.Syscall(syscall.SYS_IOCTL, 
     uintptr(syscall.Stdin), 
     uintptr(syscall.TIOCGWINSZ), 
     uintptr(unsafe.Pointer(ws))) 

    if int(retCode) == -1 { 
     panic(errno) 
    } 
    return uint(ws.Col) 
} 
+0

ここでうまくいった、ありがとう。 – Alexander

5

私がこれを簡単にするパッケージを作成しました。

https://github.com/wayneashleyberry/terminal-dimensions

package main 

import (
    "fmt" 

    terminal "github.com/wayneashleyberry/terminal-dimensions" 
) 

func main() { 
    x, _ := terminal.Width() 
    y, _ := terminal.Height() 
    fmt.Printf("Terminal is %d wide and %d high", x, y) 
} 
4

私はちょうど私が最近、この問題に遭遇したので、新しい答えを追加したいです。公式のsshパッケージhttps://godoc.org/golang.org/x/crypto/ssh/terminalの中に住んでいるターミナルパッケージがあります。

このパッケージは、端末のサイズを簡単に取得する方法を提供します。

width, height, err := terminal.GetSize(0)

0あなたはの大きさをしたい端末のファイルディスクリプタだろう。 fdまたは現在の端末を取得するには、いつでも行うことができますint(os.Stdin.Fd())

カバーの下では、指定されたfdの端末サイズを取得するためにシステムコールが使用されます。

関連する問題