func (shell ShellRunner) ExecuteStdIn(cmd string, args []string, env map[string]string, stdin io.Reader) ([]byte, error) {
	preparedCmd := exec.Command(cmd, args...)
	preparedCmd.Dir = shell.Dir
	preparedCmd.Env = mergeEnv(os.Environ(), env)
	preparedCmd.Stdin = stdin
	return Output(preparedCmd, &logWriterGenerator{
		log: shell.Logger,
	})
}
Execute a shell command
package helmexec
import (
	"bytes"
	"errors"
	"fmt"
	"io"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"syscall"
	"go.uber.org/zap"
)
const (
	tmpPrefix = "helmfile-"
	tmpSuffix = "-exec"
)
type Runner interface {
	Execute(cmd string, args []string, env map[string]string) ([]byte, error)
	ExecuteStdIn(cmd string, args []string, env map[string]string, stdin io.Reader) ([]byte, error)
}
type ShellRunner struct {
	Dir string
	Logger *zap.SugaredLogger
}
func (shell ShellRunner) Execute(cmd string, args []string, env map[string]string) ([]byte, error) {
	preparedCmd := exec.Command(cmd, args...)
	preparedCmd.Dir = shell.Dir
	preparedCmd.Env = mergeEnv(os.Environ(), env)
	return Output(preparedCmd, &logWriterGenerator{
		log: shell.Logger,
	})
}