Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

add check for set e and operator#2237

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Open
jchorl wants to merge1 commit intokoalaman:master
base:master
Choose a base branch
Loading
fromjchorl:jchorl/eand

Conversation

@jchorl
Copy link

Add a new rule to check for&& usage withset -e set.

Recently I got burned byhttps://unix.stackexchange.com/questions/312631/bash-script-with-set-e-doesnt-stop-on-command/318412#318412

I'm pretty new to Haskell so I figured I'd start small. In the future, we could expand this to includeif,while,||, etc.

While this rule is very broad-reaching, I believe it to be helpful.

Looking for advice on:

  1. Is this a reasonable thing toinfo on?
  2. What else is required to add a new rule (e.g. adding the wiki page)?
  3. Is the implementation idiomatic haskell?

For some backstory on why this is useful:

I had a script like:

#!/bin/bashset -e(exit 1) && echo "hello"exit_code="$?"echo command exited "$exit_code"

This actually printscommand exited 1, while I'd expect it to not even make it to theecho.

The following script doesnot make it to the echo:

#!/bin/bashset -e(exit 1)exit_code="$?"echo command exited "$exit_code"

To me this was extremely unintuitive and I wish shellcheck would have warned me.

Cons-Cat, Nkmol, zachriggle, schorlton, TinCanTech, DoxasticFox, and Porsh33 reacted with thumbs up emoji
@koalaman
Copy link
Owner

set -e certainly hasmany issues.

Part of what it does is to forego exiting when a failing command is used as a condition, such as withif,while and&&. It can certainly be surprising, but it's also one of the primary purposes of the mode, so always warning on all of them could get noisy. There are also some corner cases:

# Probably not expected to exitif [ -e .bashrc ] && [ -e .kshrc ]; then ...; else ...; ficd foo && ./configure || true[[ $verbose ]] && set -x# Does exit on failurescript_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

Is the expectation that the user will rewrite AND-lists into; lists orif statements depending on whether they do or don't want the script to exit when the condition fails?

@jchorl
Copy link
Author

Thanks for the response! Agreed that-e has issues - my hope is to leverage shellcheck to help users better understand and navigate unexpected behaviour.

Is the expectation that the user will rewrite AND-lists into ; lists or if statements depending on whether they do or don't want the script to exit when the condition fails?

I could think of a couple remediations given this warning:

  1. Rewrite the&& list intoif if they do not want the script to exit upon failure of the condition check (this is way more intuitive to me - you would expectif foo to not error iffoo is false). IMO; lists shouldalso be treated similarly (why not separate onto multiple lines) because they're also subject to this footgun.
  2. Add some kind of#shellcheck-ignore above the line to say "yes I'm sure I don't want the script to exit if anything in the pipeline is false"

If we wanted to make this more user friendly, we couldnot warn if the line ends with|| true or other common cases where it's clear the user knows what they're doing.

I'm not particularly tied to any specific implementation - just feel that there is an opportunity here to help users avoid a footgun. However we go about that is 👍

@koalaman
Copy link
Owner

; lists are fortunately not subject to this, but yes, I think this makes sense.

If the&& is:

  • not in a context where exit would already be ignored, such as a condition inif/while or left of||
  • not the a context where failurewould be immediately followed by exit, such as in the last and/or-list in the script, subshell, command expansion, or process substitution.

then suggest rewriting it viaif or;/linefeed

Obviously this increases the complexity a bit and is not fair to ask of this small PR, but let me know if you'd still like to give it a whack. All the information can be deduced from walking the list of parent elements (getPath (parentMap params) x), and the first point is already done via the functionisCondition which could also be adapted into aisFinalCommandInShell or similar.

@jchorl
Copy link
Author

I'm on vacation, might as well mess around with haskell. I'll take a stab at it over the next week and see what happens.

koalaman reacted with thumbs up emoji

@uri-canva
Copy link

This check would be quite useful, the more I thought about it the more confused I got, so I tested out the whole truth table of common logical operators:

evaluate_boolean() {local expression="$1"local output    output=$(bash -c"set -e;$expression; echo end")local rceval"$expression"    rc=$?if [["$output"=="end" ]];thenecho"$expression returns${rc} and continues"elseecho"$expression returns${rc} and exits"fi}whileread -r expression;do    evaluate_boolean"$expression"done<<EOFfalse && truefalse || truetrue && falsetrue || falsetrue && truetrue || truefalse && falsefalse || false! true! falsetruefalseEOF
false && true returns 1 and continuesfalse || true returns 0 and continuestrue && false returns 1 and exitstrue || false returns 0 and continuestrue && true returns 0 and continuestrue || true returns 0 and continuesfalse && false returns 1 and continuesfalse || false returns 1 and exits! true returns 1 and continues! false returns 0 and continuestrue returns 0 and continuesfalse returns 1 and exits

With|| exit codes and whetherset -e will cause the shell to exit or not matches, but&& and even! can have unintuitive behaviours.

My highlight isfalse && false returns 1 and continues.

These results are very confusing so I'd love my script to have some bug I've missed, but I've tested the most egregious results in a plain shell and could reproduce them.

DoxasticFox and paulszabo reacted with thumbs up emoji

@uri-canva
Copy link

uri-canva commentedAug 20, 2021
edited
Loading

The documentation forset -ehttps://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#set explains it, but it's still very unintuitive.

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

No reviews

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

3 participants

@jchorl@koalaman@uri-canva

[8]ページ先頭

©2009-2025 Movatter.jp