4

我提供带有几个命令和子命令的命令行工具,我使用cobra命令行,我有两个单独的命令 ,首先是其他命令的先决条件

例如,第一个命令是通过创建临时文件夹并验证某些文件来首选环境

第二个命令应该从第一个命令中获取一些属性

用户应该像这样执行它

btr 准备
btr 运行

执行时,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 个命令的 shell 脚本运行命令行命令,然后调用需要从第一个命令,我需要 E2E解决方案和我的上下文中的代码实例

更新 2

假设我知道我需要配置文件(json),

我应该在哪里创建它(路径)?

什么时候清洗呢?

如果我使用 1file 我应该如何验证以存储与特定流程相关的数据并在需要时获取其他流程数据(guid)?

可以说我的配置如下

type config struct{
    
    path string,
    wd string,
    id string,//guid?
    
}
4

2 回答 2

2

如果您尝试在执行命令行工具的不同命令时保持状态,您有 2 个选择。

  1. 将状态写入某种文件(在这种情况下考虑 env 文件)。
  2. 以可用作另一个命令的输入的方式从第一个命令输出值。

在 1。

我认为对于任何参数等来说,仅在 CLI 工具运行的生命周期内存活是一种很好的做法。相当于编程中可能的最小范围变量。当您需要无限期地保持状态时,这很有效,但如果您的状态在命令完成后不再使用,initProcess那么这可能不是正确的选择。

在 2。

这有一些优先级。unix 哲学(维基百科)建议:

期望每个程序的输出成为另一个程序的输入

因此,您可以为第一个命令选择一些输出(到标准输出)格式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
于 2018-04-23T13:08:09.680 回答
2

在命令之间共享信息

就像评论中所说的那样,如果您需要跨命令共享数据,则需要将其持久化。您使用的结构无关紧要,但为了简单起见,并且由于 JSON 是当前用于数据交换的最扩展语言,我们将使用它。


我应该在哪里创建它(路径)?

我的建议是使用用户的家。许多应用程序将其配置保存在这里。这将轻松实现多环境解决方案。假设您的配置文件将命名为myApp

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


什么时候清洗呢?

这显然取决于您的要求。但是,如果你总是需要按这个顺序运行prerun我敢打赌你可以在run执行后立即清理它,当它不再需要时。


如何储存?

这很容易。如果你需要保存的是你的config结构,你可以这样做:

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`

免责声明:我已经删除了所有的错误处理。

于 2018-04-28T05:19:16.220 回答