script icon indicating copy to clipboard operation
script copied to clipboard

Exit method

Open bitfield opened this issue 2 years ago • 5 comments

Several people have noted that the behaviour of Stdout is a bit puzzling when there's an error in the pipe, especially for beginners: it just prints nothing! Unless the program checks the return value of Stdout, there's nothing to indicate that an error happened.

To make it easier to write one-liners, I propose an Exit method that behaves like Stdout, but also prints any pipe error to stderr and calls os.Exit with the appropriate exit status. For example:

script.Get(URL).Exit()

Depending on the HTTP response, we might see as a result:

HTTP/1.1 404 Not Found

with

echo $?
1

bitfield avatar Nov 12 '22 11:11 bitfield

Some ideas about this feature, however, having if they have to delay this for quite a while, I'd suggest ignoring them and doing them in the future.

  • Printing the error to stderr is a good idea, but it would be nice to have available some methods that allow redirecting outputs, if it isn't in a generic way, at least to redirect stderr to stdout.
  • Have the ability to specify and specific exit code, rather than always returning 1.
  • Have the ability to add a prefix to the error message, like "ERROR: ", but then there may be a way to implement something to modify anything before calling the sink, however, Filter looks like that can do that despite that its name doesn't suggest it and it has another purpose.

ifraixedes avatar Dec 12 '22 09:12 ifraixedes

Have the ability to specify and specific exit code, rather than always returning 1.

This is an interesting idea—can you comment with a short program showing how this might be used?

bitfield avatar Dec 12 '22 16:12 bitfield

Following your example, it could be as simple as passing the exit code to the Exit method.

script.Get(URL).Exit(100)

Depending on the HTTP response, we might see as a result:

HTTP/1.1 404 Not Found

with

echo $?
100

When I thought about this is because I wanted to simplify the following

if err := script.Exec("sudo apt-get update").Stdout(); err != nil{
  fmt.Fprintf(os.Stderr, "Aborting error: %+v", err)
  os.Exit(100)
}

But this example would require some of the other things, one of them being the 3rd bullet point that I wrote above.

Perhaps, it could exist a method like OutputExit(code int), which would print to stdout if no error from "filter", otherwise print to stderr and exit with code.

ifraixedes avatar Dec 13 '22 13:12 ifraixedes

script.Get(URL).Exit(100)

Under what circumstances would it make sense to do this? It looks to the reader as though the script is going to exit with status code 100, no matter what the result of the Get—and if you're going to do that, you may as well call os.Exit(100) directly.

I can't see a value in a pipe method that sets the exit status unless it somehow reflects the status of the pipeline as a whole.

bitfield avatar Dec 13 '22 13:12 bitfield

I didn't get that far thinking that some use case is to change the exit code depending on the result of the pipe. That would be even better!

My use case was simpler, in my script I may want to return a different exit code depending on the operation to easily distinguish between them.

For example, imagine that the script does an installation part and then a configuration part of a system. I'd like to have an exit code when running commands that do the installation part (e.g. apt-get install xxx) and another exit code when doing the configuration (e.g. psql .....).

This allows me from other applications to quickly distinguish at what stage the script failed.

ifraixedes avatar Dec 14 '22 10:12 ifraixedes