-
-
Notifications
You must be signed in to change notification settings - Fork 4
Description
true || echo $(rm -rf /) # Will NEVER delete any files
false && echo $(rm -rf /) # Will NEVER delete any filesSupershells however are evaluated in advance of the line that asks for them, and their result stored in a variable so that they can be accessed where needed. Therefore:
true || echo @(rm -rf /) # Will delete your files
false && echo @(rm -rf /) # Will delete your filesBecause the compiler spots the supershell, and evaluates it on the line before.
This was noticed while working on #8
echo ${var_which_does_not_exist-$(echo hi | tee file)} # Echoes "hi", creates 'file', and write "hi" to that file
echo ${var_which_exists-$(echo hi | tee file)} # Echoes the contents of $var_which_exists, does NOT create any files or write to any filesIf supershells are not changed, they would be evaluated in the case that we use them in parameter expansion as well, even when not needed
Another example of the same problem:
if condition1; then
some-action
elif [[ @(supershell) == "expected output" ]]; then
some-other-action
fiIn this case, the supershell will again be evaluated before the entire conditional, where it should only be evaluated in the event that the first condition was false
Possible solution: equivalent logic re-writing. Watch for connectives, parameter expansions, etc, cases where the program flow is determined at runtime, and re-write the logic in an equivalent way. For example:
true || echo @(rm -rf /)Could be automatically re-written to the equivalent:
if ! true; then
echo @(rm -rf /)
fiOr:
echo ${var_which_exists-@(echo hi | tee file)}Could be automatically re-written to the equivalent:
temporary_variable=
if [[ -v var_which_exists ]]; then
temporary_variable=${var_which_exists}
else
temporary_variable=@(echo hi | tee file)
fi
echo ${temporary_variable}
unset temporary_variableThat last case (with the IFs) would not have to be rewritten, but could simply be compiled so that the supershell evaluation is part of the conditional (as we do in while statements already)
I'm not a big fan of this solution, since the logic requires different specific courses of action in different specific cases, as opposed to being a general solution for all such cases.