Home > Backend Development > Golang > How to run foreground or background shell commands in Go

How to run foreground or background shell commands in Go

WBOY
Release: 2024-02-08 22:57:31
forward
1154 people have browsed it

如何在 Go 中运行前台或后台 shell 命令

php editor Apple introduces you how to run foreground or background shell commands in Go. In Go language, running shell commands is very simple. By using the os/exec package, we can easily execute various shell commands and get their output. Whether running foreground commands or background commands, Go language provides corresponding methods. In this article, we will learn how to run front or background shell commands using Go language and explore some common use cases. let's start!

Question content

In go, I need to be able to run shell commands from the user and only block commands running in the foreground (not run using &) while retrieving The output of the command.

For example, in bash we can:

#!/bin/bash
while read -p 'enter a command: ' cmd; do
    /bin/sh -c "$cmd" >(sed 's/^/line of output: /')
done
Copy after login

Users can enter a foreground command like sleep 5; echo hi which will block and the prompt does not reappear immediately, or they can enter a background command like { sleep 5; echo hi; & and it doesn't block and the prompt reappears immediately while the command is running in the background.

How do I recreate it in go? Here's my attempt:

package main

import (
    "bufio"
    "os"
    "os/exec"
)

func main() {
    input := bufio.newscanner(os.stdin)
    for {
        print("enter a command: ")
        input.scan()
        cmd := exec.command("/bin/sh", "-c", input.text())
        stdout, err := cmd.stdoutpipe()
        if err != nil {
            panic(err)
        }
        go func() {
            output := bufio.newscanner(stdout)
            for output.scan() {
                println("line of output: " + output.text())
            }
            if output.err() != nil {
                panic(output.err())
            }
        }()
        if err := cmd.start(); err != nil {
            panic(err)
        }
        if err := cmd.wait(); err != nil {
            panic(err)
        }
    }
}
Copy after login

Running sleep 5; echo hi blocks and works, but { sleep 5; echo hi; } & Error:

panic: read |0: file already closed
Copy after login

For context, I ported voice control to go, where users can configure actions such as runtype where their commands are run through a shell and simulate keystrokes for typing output. Users can use background commands so that voice control continues along with the command, for example they can launch a menu when saying "menu" and still be able to use voice control while it's open: menu: runtype printf %s\\n This and that | dmenu &.

Solution

This behavior can be achieved by setting stdout to a named pipe.

The above is the detailed content of How to run foreground or background shell commands in Go. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:stackoverflow.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template