[1]: https://prettier.io
I'll go further. PowerShell covers a lot of the concerns in the OP out of the box. It is extremely well thought out and is one of my favorite cli models to buy into.
I use MacOS on my personal machine and Linux for various shellboxes and I switched to Powershell years ago and haven't looked back. Occasionally I invoke bash as a language runtime for checking shell script stuff, the way I would any other language's REPL, but for a shell? Powershell is strictly better.
The one actual problem with Powershell in this area is quoting for external commands. It's solvable in scripts by replacing certain things with double-quoted equivalents but not really interactively, and it is an occasional pain (though I still think it's overall less of a problem than quoting in general in bash and its ilk).
I feel it’s safer for scripts that have irreversible (or difficult to reverse) actions.
Instead of
myprog # see what would happen
myprog --commit # alright, do it
You do myprog # see what would happen
myprog | sh # alright, do it
But if you want to change something: myprog > x
vi x
cat x | sh
And if you just want to run everything in parallel: myprog | parallel -j 16If you call an API to retrieve data, how can that be a dry run? Are you suppose to give fake examples with fake output?
Calling an API to retrieve data is not really the type of program that requires a dry-run flag. It's mainly useful for commands that change the state of something in ways that could potentially be destructive, unwanted and/or hard to revert.
https://docs.aws.amazon.com/cli/latest/userguide/cli-usage-h...
> do_thing.py | dry-run
--
Think of it as "explain your work, step by step" as one would prompt...
also, its a food-for-thought you muppets.
---
@jasonjmcghee ; ( $ ) . ( $ ) great justice.
But at that point you could just handle —dry-run directly
You can do that. Possibly not from all languages but for anything that can call functions in the c standard library, that’s what isatty() is for (among other uses). It takes a file descriptor and returns whether it is a terminal or not. If you do this with stdout, this tells you whether it goes to a terminal or whether it is redirected in a way.
As the parent suspects, though, this won’t tell you anything about what is on the other side of the redirection.
-
What if there wasa 'deep-pipe' '||' which would be based on a set env/docker/blah - which would launch an env and execute your '||'d code in it, and output some log/metrics/whatever?
The output sent to tee is usually not the same as the output from the command to the terminal, so you are getting something different than most human users expect from original command... the reason is that terminal escape codes and other formatting for humans may need to be omitted from output to a pipe. You do this by asking the OS, "is this thing a terminal?".
Python example
"terminal" if sys.stdout.isatty() else "something else"
C is very similar:
if (isatty (1)) fprintf (stdout, "Terminal."); else fprintf (stdout, "Not Terminal.");
(printf works, too).
Even ls outputs a tabular format by default when it's on a terminal and a list one file/dir per line when it's not on a terminal (if it's piped to cat for example or why ls | wc -l correctly counts the entries).
But the (essential) behavior of the command remains the same. ls still lists files/dirs... scp still copies files, etc.
Of course. A command needs to do it's defined function.
You'll find some programs that are quite a bit different when invoked from outside the terminal vs inside the terminal. Developers need to take into account both situations, which is really the point the original post.
One approach could be something like “set -x” after setting a confirmation with “trap” command.
confirm_execution() {
echo -n "Execute $BASH_COMMAND? [y/N] "
read response
if [[ $response != [yY] ]]; then
echo "Skipped."
return 1
fi
}
trap 'confirm_execution' DEBUG
set -x
user_command
set +x
But that’s a wrapper scriptdraw_heart() { cat << EOF <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="100" height="100"> <path fill="red" d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"/> </svg> EOF }
trap 'confirm_execution' DEBUG set -x draw_heart set +x