Remove unnecessary `cd` commands; Output errors to stderr (#40)

As discussed in a YouTube comment (https://www.youtube.com/watch?v=KEWhOzDCfLg&lc=UgzqmZf7hgBRjGLe-Pp4AaABAg), the `cd` commands to "return" back to the original directory are unnecessary, because it is *impossible* for a script to change the working directory of a shell.

When you run a `cd` command in a script, the working directory does change, but only for the script. When the script exits, nothing has happened to the working directory of the shell where you ran the script.

In fact, it is *impossible* for a script to change the working directory of the shell, even if you wanted to do that. Some ways you can change the working directory:
- an alias that runs a `cd` command (an alias is equivalent to running the commands in your shell)
    - `alias gohome="cd ~"
- a shell function that runs a `cd` command (this is the primary reason why things like z.lua are implemented as a shell function, not a script)
    - `function gohome() { cd ~ }`
- sourcing a script (so there is a way to do it with a script, but you have to run the script in a specific way, and this will also make exit quit the shell, not just the script)
    - `source ./script-name`

These are the ways I know of doing it, there may be some others.

Even if a script could change the shell's working directory, `fla.sh` is doing `cd "$PWD"`, which is basically a no-op, because `$PWD` is automatically updated:
```bash
echo "$PWD"

# go to the flashcard decks directory
cd "$DIR"

echo "$PWD"
```

The above outputs:
```
/home/sami
/home/sami/.local/share/flash
```

So, doing `cd $PWD` actually would not return back to the original directory, it would stay in whatever directory you've cd'd into.

-----

Another minor change in this PR is to output errors to stderr instead of stdout (before this change, errors were output to stdout).

With `fla.sh`, this doesn't really make much of a difference, but generally you want to output errors to stderr. This is useful, if you want to run a script quietly, but still want to see errors. If errors are output to stderr, this can be done with by running e.g.:
```bash
./script-name > /dev/null
```

The above will hide all regular output (redirecting stdout to `/dev/null`), but will still show anything output to stderr (i.e. error messages). To also hide error messages (make a script run completely silently), you can run:
```bash
./script-name > /dev/null 2>&1
```

The above `2>&1` syntax redirects stderr (`2>`) to the same place where stdout is redirected, and `> /dev/null` is redirecting stdout to `/dev/null`.

To only hide error messages, but show regular output, you could run `./script-name 2> /dev/null`, but that might not be a smart thing to do (if there are errors, you probably want to know about them).

The proposed change uses `>&2`, which redirects stdout to stderr, so that regular print commands (e.g. `echo`) are displayed on stderr. Both stdout and stderr are shown similarly in a terminal, but they're still separate, so they can be redirected, etc. Some terminals may also show stderr messages differently.

Both `echo "..." >&2` and `>&2 echo "..."` work identically, but I've used `>&2 echo "..."` because I think it's more intentional ("the following output is an error"), and if there's a long error message, the `>&2` could get "lost" at the end of a line. I picked it up on Stack Overflow, and I've used it ever since:
https://stackoverflow.com/a/23550347
This commit is contained in:
Sami Kankaristo 2021-01-25 00:52:57 +02:00 committed by GitHub
parent f5ebff2e15
commit 8915b54e22
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 6 additions and 6 deletions

12
flash
View File

@ -129,7 +129,7 @@ if [ ! -d "$DIR" ]; then
case "$RESPONSE" in case "$RESPONSE" in
[QqNn]) exit 0 ;; [QqNn]) exit 0 ;;
[Yy]) setup && exit 0 ;; [Yy]) setup && exit 0 ;;
*) echo -e "invalid choice, please select either ${LGREEN}y${NC} or ${LRED}n${NC}" && exit 1 ;; *) >&2 echo -e "invalid choice, please select either ${LGREEN}y${NC} or ${LRED}n${NC}" && exit 1 ;;
esac esac
fi fi
@ -139,7 +139,7 @@ cd "$DIR" || exit 1
# If there are no flashcard decks available return user to starting location # If there are no flashcard decks available return user to starting location
# while also displaying explanatory text of issue # while also displaying explanatory text of issue
[ "$(find . -maxdepth "$SEARCH_DEPTH" -iname "*.csv" | wc -l)" = 0 ] && [ "$(find . -maxdepth "$SEARCH_DEPTH" -iname "*.csv" | wc -l)" = 0 ] &&
echo -e "$NO_DECKS" && cd "$PWD" && exit 1 >&2 echo -e "$NO_DECKS" && exit 1
# if highscore file was removed, remake it. # if highscore file was removed, remake it.
[ ! -e "$HIGH_SCORE" ] && touch "$HIGH_SCORE" [ ! -e "$HIGH_SCORE" ] && touch "$HIGH_SCORE"
@ -199,7 +199,7 @@ while getopts 'hivp:' flag; do
h) print_usage && exit 0 ;; h) print_usage && exit 0 ;;
i) print_info && exit 0 ;; i) print_info && exit 0 ;;
v) echo -e "\n${YELLOW}fla.sh Current Version:${NC} ${RED}1.2${NC}\n" && exit 0 ;; v) echo -e "\n${YELLOW}fla.sh Current Version:${NC} ${RED}1.2${NC}\n" && exit 0 ;;
p) { [[ $(command -v "$OPTARG" 2>&1) ]] && PREVIEWER=$OPTARG; } || echo "Unable to find previewer $OPTARG. Exiting..." && exit 1 ;; p) { [[ $(command -v "$OPTARG" 2>&1) ]] && PREVIEWER=$OPTARG; } || >&2 echo "Unable to find previewer $OPTARG. Exiting..." && exit 1 ;;
*) print_usage && exit 1 ;; *) print_usage && exit 1 ;;
esac esac
done done
@ -254,7 +254,7 @@ add_usage_entry() {
# If no deck is selected in fzf menu # If no deck is selected in fzf menu
# return user to start location # return user to start location
# and exit quietly # and exit quietly
[ -z "$DECK" ] && clear && cd "$PWD" && exit 1 [ -z "$DECK" ] && clear && exit 1
main() { main() {
IFS=$':' IFS=$':'
@ -272,7 +272,7 @@ ${LGREY}──────────────── Press [Enter] to contin
done done
clear clear
print_head print_head
{ [ "$NEXT" = q ] || [ "$NEXT" = Q ]; } && add_usage_entry && cd "$PWD" && clear && exit 0 { [ "$NEXT" = q ] || [ "$NEXT" = Q ]; } && add_usage_entry && clear && exit 0
ANSWER=$(echo "${q[2]}" | fold -w 59) ANSWER=$(echo "${q[2]}" | fold -w 59)
@ -294,7 +294,7 @@ ${LGREY}Select a number to continue, or${NC} ${LRED}Q${NC} ${LGREY}to quit...${N
read -sn 1 DIFFICULTY_SCORE read -sn 1 DIFFICULTY_SCORE
done done
{ [ "$DIFFICULTY_SCORE" = q ] || [ "$DIFFICULTY_SCORE" = Q ]; } && { [ "$DIFFICULTY_SCORE" = q ] || [ "$DIFFICULTY_SCORE" = Q ]; } &&
add_usage_entry && cd "$PWD" && clear && exit 0 add_usage_entry && clear && exit 0
clear clear
COUNTER="$((COUNTER + 1))" # Increment count for card review count increment COUNTER="$((COUNTER + 1))" # Increment count for card review count increment