urfave / cli

A simple, fast, and fun package for building command line apps in Go

Home Page:https://cli.urfave.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

How do you set up cliv2 for command line inputs $ cli_command < input.txt > output.txt

wakatara opened this issue · comments

I'm re-writing an old fortran 77 piece of code into Go. The scientists are used to using it like:

water < input_file.txt 

and then having it walk them through the command parameters it needs (druid style).

I googled and looked and can't seem to find any documentation on how to accomplush that (though assume if I make the input file the first expected argument it might work? I thought I should ask the question since I haven't seen it mentioned anywhere in the docs (or missed it totally) and I imagine other people might want to find this for the google juice it gives.

thanks!
PS> I've already used cliv2 to write one of my long standing little cli apps, harsh and it's been great, so just wanted to say thanks for writing a simple, easy to use framework that doesn't overcomplicate. I prefer cliv2 over all the alternatives I evaluated.

@wakatara There are multiple ways to do this

cat input_file.txt | xargs water

or

water $(< input_file.txt )

Hmmm... interesting. Thanks for the quick response. Is there any way to support the water < input_file.txt convention? Mostly because it is a learned behaviour amongst the science folks I am dealing with, and I imagine any deviation from what they're used to is gonna cause moans.

Out of curiosity, is there any way to have the cli v2 handle that argument syntax in the future? (I find most people do not know how to use xargs but are familiar with the < > and | operators. Also, I have to admit... I would not even have guessed at the
water $(< input_file.txt )

Have never seen that one before, myself. (though am not exactly a bash expert.... :-/ ).

@wakatara I guess that the

water < input_file.txt

works on Windows/DOS cmdline ? otherwise you are going against Unix/Bash conventions. Here are some options https://stackoverflow.com/questions/6980090/how-to-read-from-a-file-or-standard-input-in-bash

cli v2 will definitely not support this. If you'd like it can be considered for v3

No, this is totally how it gets done on linux/unix, I mean... with almost every utility I've ever used. Something like:

$ water < input.txt > output.txt

is very common afaik. And certainly in science with most cli apps.

Would love for it to be considered for v3. I have to admit I thought it was strange it did not work that way.

Wy do you say it goes against unix/bash conventions. I mean, I think I've used this pattern with cli apps for over 20 years. cliv2 not supporting it surprised me.

Ah sorry yes it is the unix way :headslap . But the intent of the < operator is different. The < operator sends the contents of the file to stdin of the process. Thats different from the args that the process consumes. Here is an example

$ cat > ~/scratch/tmp.args
-al
$ ls < ~/scratch/tmp.args
go.mod  go.sum  main.go
$ ls -al
total 20
drwxr-xr-x  2 foo foo 4096 May 16 10:45 .
drwxr-xr-x 55 foo foo 4096 May 16 10:41 ..
-rw-r--r--  1 foo foo  335 May 16 14:18 go.mod
-rw-r--r--  1 foo foo 764 May 16 10:47 go.sum
-rw-r--r--  1 foo foo 650 May 16 10:47 main.go
$ ls < ~/scratch/tmp.args
go.mod  go.sum  main.go

@wakatara I've been thinking about this a bit more. You can have your cli app do this

       app := &App{...}
        b, err := io.ReadAll(os.Stdin)
	if err != nil {
		panic(err)
	} 

       app.Run(strings.Split(string(b), "\n"))

That should give you the behavior you want.

@dearchap

Hmmm... this looks good! I am just about to try it out and see if it works in a bit.

Just a question though... if I am rewriting this app (cause the original fortran 77 code won't even compile on a modern fortran compiler anymore... 8-// ), so that I am using a combo of switches and want to use directed input:

$ sublimate --volitile 18.0 --albedo 0.04 --radius 1000 --phasefunc 0.04 < input.txt

I am assuming this approach does not work? (have not tried it, but that's kinda where I want to take the new cli.

PS> Omg though. Thanks so much for continuing to think about this and taking a shot at it. I would not have thought of that approach tbh.

@wakatara

This should give you the behavior you want

    args := []string{}
    app := &App{...}
        b, err := io.ReadAll(os.Stdin)
	if err != nil {
		panic(err)
	} 

     split_input = strings.Split(string(b), "\n")
      args = append(args, os.Args...)
      args = append(args, split_input...)
      app.Run(args)

@wakatara I am closing this for now since there are no changes on urfave/cli for this.

@wakatara

This should give you the behavior you want

    args := []string{}
    app := &App{...}
        b, err := io.ReadAll(os.Stdin)
	if err != nil {
		panic(err)
	} 

     split_input = strings.Split(string(b), "\n")
      args = append(args, os.Args...)
      args = append(args, split_input...)
      app.Run(args)

This looks great. I am quite sure I would not have puzzled this out. Thanks so much. Would love to see this baked into v3 though!

@wakatara I'm going to reopen this and see if we can push this into v3.

Awesome. Sounds amazing. 😁

@wakatara Here's the fix in v3 !!!!

@dearchap

Woo!! Thank you! Excellent timing as I am working on something for this (and an older app based on v2 over xmas. =]
Thanks for all your work on this!

@dearchap Just checked version numbers on the repo. When are you thinking of cutting the 3.0 release?