func (cmd Command) createAction() func(c *cli.Context) {
	action := func(c *cli.Context) {
		commands := regexp.MustCompile(`[;]`).Split(cmd.Action, -1)
		for _, commandStr := range commands {
			commandStr := strings.TrimSpace(commandStr)
			commandArr := strings.Split(commandStr, " ")
			command := commandArr[0]
			args := append(commandArr[1:], c.Args()...)
			cmd := exec.Command(command, args...)
			fd := os.Stdin.Fd()
			oldState, err := terminal.MakeRaw(int(fd))
			if err != nil {
				log.Fatal(err)
			}
			defer terminal.Restore(int(fd), oldState)
			tty, err := pty.Start(cmd)
			if err != nil {
				log.Fatal(err)
			}
			defer tty.Close()
			go func() {
				io.Copy(os.Stdout, tty)
			}()
			go func() {
				io.Copy(tty, os.Stdin)
			}()
			err = cmd.Wait()
			if err != nil {
				terminal.Restore(int(fd), oldState)
				log.Fatal(err)
			}
		}
	}
	return action
}
createAction will return a closure that will be used as Action for a
cli.Command
package main
import (
	"encoding/json"
	"io"
	"log"
	"os"
	"os/exec"
	"regexp"
	"strings"
	"golang.org/x/crypto/ssh/terminal"
	"github.com/kr/pty"
	"github.com/urfave/cli"
)
type App struct {
	Name     string       `json:"name"`
	Usage    string       `json:"usage"`
	Authors  []cli.Author `json:"authors"`
	Version  string       `json:"version"`
	Commands []Command    `json:"commands"`
}
type Command struct {
	Name   string `json:"name"`
	Usage  string `json:"usage"`
	Action string `json:"action"`
}