(sed's/^/lineofoutput:/')doneThe user can enter something like sleep5 Such a foreground command; echohi will block and the prompt will not reappear immediately, or they can enter a background command like"/> (sed's/^/lineofoutput:/')doneThe user can enter something like sleep5 Such a foreground command; echohi will block and the prompt will not reappear immediately, or they can enter a background command like">

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

How to run foreground or background shell commands in Go

WBOY
WBOYforward
2024-02-08 22:57:311136browse

如何在 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

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)
        }
    }
}

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

panic: read |0: file already closed

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!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete