从单独的命令/进程

时间:2018-04-23 06:52:08

标签: go command-line command-line-arguments viper-go go-cobra

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

e.g。第一个命令是通过创建临时文件夹并验证某个文件来优先选择环境

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

并且用户应该像

一样执行它
  

btr准备
  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)

}

更新

嗯,下面的答案确实有帮助。我需要在本地&amp;中的两个命令之间共享状态。 cloud env),我怎么能这样做,如果我从调用1命令的shell脚本运行命令行命令然后调用第二个需要从第一个命令获得某个状态的命令,我需要E2E < strong>在我的上下文中使用代码实例的解决方案

更新2

让我说我明白我需要配置文件(json),

  

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

     

何时清洁?

     

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

让我说我配置如下

type config struct{

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

}

2 个答案:

答案 0 :(得分:2)

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

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

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

    On 2。

    这有一些优先权。 unix哲学(wikipedia)建议:

      

    期望每个节目的输出成为另一个节目的输入

    因此,您可以为第一个prepare命令选择一些输出(to stdout)格式,该命令可用作第二个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
    

答案 1 :(得分:1)

在命令之间共享信息

就像评论中所说,如果你需要跨命令共享数据,你需要坚持下去。您使用的结构不相关,但为了简单起见,由于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`
  

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