Open
Description
What version of Go are you using (go version
)?
$ go version go version go1.17.1 darwin/amd64
Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (go env
)?
go env
Output
$ go env GO111MODULE="" GOARCH="amd64" GOBIN="" GOCACHE="/Users/a17847869/Library/Caches/go-build" GOENV="/Users/a17847869/Library/Application Support/go/env" GOEXE="" GOEXPERIMENT="" GOFLAGS="" GOHOSTARCH="amd64" GOHOSTOS="darwin" GOINSECURE="" GOMODCACHE="/Users/a17847869/go/pkg/mod" GONOPROXY="" GONOSUMDB="" GOOS="darwin" GOPATH="/Users/a17847869/go" GOPRIVATE="" GOPROXY="https://proxy.golang.org,direct" GOROOT="/usr/local/go" GOSUMDB="sum.golang.org" GOTMPDIR="" GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64" GOVCS="" GOVERSION="go1.17.1" GCCGO="gccgo" AR="ar" CC="clang" CXX="clang++" CGO_ENABLED="1" CGO_CFLAGS="-g -O2" CGO_CPPFLAGS="" CGO_CXXFLAGS="-g -O2" CGO_FFLAGS="-g -O2" CGO_LDFLAGS="-g -O2" PKG_CONFIG="pkg-config" GOGCCFLAGS="-fPIC -arch x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/9y/91hpvx4d4kj786gtvh7j45180000gp/T/go-build1991588269=/tmp/go-build -gno-record-gcc-switches -fno-common"
What did you do?
- I created a simple program that will run on remote machine via SSH:
func main() {
fmt.Println("> remote program started")
ch := make(chan os.Signal, 1)
signal.Notify(ch, syscall.SIGINT)
sig := <-ch
fmt.Println("\n> remote program got signal:", sig)
fmt.Println("> remote program finished")
}
- Compiled that code and deployed executable file to remote machine
- From local machine let's check that everything works as expected using local ssh command:
$ ssh -t {user}@{IP} /path/to/executable/file
> remote program started
^C
> remote program got signal: interrupt
> remote program finished
Connection to {IP} closed.
Everything looks good so far. When I push Ctrl+C on my keyboard I see the correct message from remote program that signal catches. Now let's repeat the same behavior using x/crypto/ssh:
func main(){
var conn *ssh.Client
/* skip connection and client initialization code */
session, err := conn.NewSession()
if err != nil {
log.Fatalf("conn.NewSession failed": %v", err)
}
defer session.Close()
stdin, err := session.StdinPipe()
if err != nil {
log.Fatalf("session.StdinPipe failed: %v", err)
}
session.Stdout = os.Stdout
session.Stderr = os.Stderr
err = session.Start("/path/to/executable/file")
if err != nil {
log.Fatalf("session.Start failed: %v", err)
}
// wait some time before interrupt
time.Sleep(5*time.Second)
// try to send SIGINT signal
err = session.Signal(ssh.SIGINT)
if err != nil {
log.Fatalf("session.Signal failed: %v", err)
}
// Also try to simulate Ctrl+C
_, err = stdin.Write([]byte("\x03"))
if err != nil {
log.Fatalf("stdin.Write failed: %v", err)
}
stdin.Close()
time.Sleep(2 * time.Second)
err = session.Close()
if err != nil {
log.Fatalf("session.Close failed:", err)
}
err := session.Wait()
if err != nil {
log.Printf("session.Wait error: %v\n", err)
}
log.Println("local program finished")
}
What did you expect to see?
When I run above code I would see the following output:
> remote program started
> remote program got signal: interrupt
> remote program finished
What did you see instead?
When I run above code I actually see the following output:
> remote program started
2021/09/30 08:54:07 session.Wait error: wait: remote command exited without exit status or exit signal