Поделиться свойствами из отдельных команд / процессов

Я предоставляю инструмент командной строки с несколькими командами и подкомандами, я использую командную строку кобры, и у меня есть две отдельные команды, которые в первую очередь необходимы другим

например, первая команда предпочитает среду, создавая временную папку и проверяя какой-либо файл

Вторая команда должна получить некоторые свойства от первой команды

и пользователь должен выполнить это как

БТР подготовить
Btr Run

когда run command выполняется, он должен получить некоторые данные из prepare командный результат

// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
    Use:   "btr",
    Short: "piping process",
}


    var prepare = &cobra.Command{
        Use:   "pre",
        Short: "Prepare The environment" ,
        Run: func(cmd *cobra.Command, args []string) {

        //This creating the temp folder and validate some configuration file    
           tmpFolderPath,parsedFile := exe.PreProcess()
        },
    }


    var initProcess = &cobra.Command{
        Use:   “run”,
        Short: “run process”,
        Run: func(cmd *cobra.Command, args []string) {

      //Here I need those two properties 

             run(tmpFolderPath, ParsedFile)
        },
    }

func init() {

    rootCmd.AddCommand(prepare,initProcess)

}

ОБНОВИТЬ

Ну, ответ ниже действительно помогает. Мне нужно разделить состояние между двумя командами в локальной и облачной среде), как я могу это сделать, если я запускаю команды командной строки из сценария оболочки, которые вызывают 1 команду, а затем вызывают вторую, которая должна получить некоторое состояние из Первая команда, мне нужно решение E2E с реальным примером кода в моем контексте

обновление 2

допустим, я понимаю, что мне нужен файл конфигурации (JSON),

Где я должен создать его (путь)?

Когда его почистить?

в случае, если я использую 1 файл Как мне проверить, чтобы хранить данные, которые имеют отношение к конкретному процессу, и принимать другие данные процесса, когда это необходимо (guid)?

скажем, я конфиг, как следующий

type config struct{

    path string,
    wd string,
    id string,//guid?

}

2 ответа

Решение

Обмен информацией между командами

Как было сказано в комментариях, если вам нужно обмениваться данными между командами, вам нужно сохранить их. Используемая вами структура не имеет отношения к делу, но для простоты и потому, что JSON является самым распространенным языком для обмена данными, мы будем его использовать.


Где я должен создать его (путь)?

Я рекомендую использовать дом пользователя. Многие приложения сохраняют свою конфигурацию здесь. Это позволит легко решить несколько задач. Скажите, что ваш файл конфигурации будет называться myApp.

func configPath() string {
    cfgFile := ".myApp"
    usr, _ := user.Current()
    return path.Join(usr.HomeDir, cfgFile)
}


Когда его почистить?

Это, очевидно, будет зависеть от ваших требований. Но, если вам всегда нужно бежать pre а также run в таком порядке, держу пари, что вы можете очистить его сразу после run исполнение, когда оно больше не будет нужно.


Как хранить это?

Это легко. Если то, что вам нужно сохранить, это ваше config struct вы можете сделать это:

func saveConfig(c config) {
    jsonC, _ := json.Marshal(c)
    ioutil.WriteFile(configPath(), jsonC, os.ModeAppend)
}


И читать это?

func readConfig() config {
    data, _ := ioutil.ReadFile(configPath())
    var cfg config
    json.Unmarshal(data, &cfg)
    return cfg
}


поток

// pre command
// persist to file the data you need
saveConfig(config{ 
    id:   "id",
    path: "path",
    wd:   "wd",
}) 

// run command
// retrieve the previously stored information
cfg := readConfig()

// from now you can use the data generated by `pre`

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: Я удалил всю обработку ошибок для краткости.

Если вы пытаетесь сохранить состояние во время выполнения различных команд инструмента командной строки, у вас есть 2 варианта.

  1. Запишите состояние в какой-то файл (в данном случае рассмотрим env файл).
  2. Выведите значения из первой команды таким образом, чтобы ее можно было использовать в качестве входных данных для другой команды.

На 1.

Я думаю, что для любых аргументов и т. Д. Будет хорошей практикой выживать только в течение всего времени работы инструмента CLI. Эквивалент самых маленьких переменных области действия, возможных в программировании. Это хорошо работает, когда вам нужно сохранить состояние на неопределенный срок, но если ваше состояние больше не используется после initProcess команда закончила, то это, вероятно, не правильный вариант.

На 2.

Для этого есть какой-то приоритет. Философия Unix ( Википедия) предлагает:

Ожидайте, что выходные данные каждой программы станут входными данными для другой

Таким образом, вы можете выбрать какой-либо выходной (для stdout) формат для первого prepare команда, которая может быть использована в качестве ввода для второго initProcess команда. А потом использовать | труба для запуска вывода одного в другой.

Пример:

func Run(cmd *cobra.Command, args []string) {
    //This creating the temp folder and validate some configuration file    
    tmpFolderPath,parsedFile := exe.PreProcess()
    fmt.Println(tmpFolderPath)
    fmt.Println(parsedFile)
}

func InitProcess(cmd *cobra.Command, args []string) {

    tmpFolder, parsedFile := args[0], args[1]

}

Затем запустите программу и передайте команды вместе:

./program pre | xargs ./program run
Другие вопросы по тегам