A command you can type in a terminal and a script you can hand to someone else are two different things. Shebangs and execute permission, quoting, set -euo pipefail, getopts, trap, locking, ShellCheck and bats. Twenty lessons that turn "a procedure only you can run" into "a script that does not break on someone else's machine".
The 20 lessons are grouped into five chapters. Working through them in order is the best way, but you are welcome to read only the part you are stuck on right now. Note: shell commands cannot run inside the browser. Try them in your own terminal (on macOS, Homebrew's bash 5.x).
What changes between typing at a terminal and writing a file you hand over. Shebangs and execute permission, quoting and word splitting, and set -euo pipefail. Get this wrong and the other seventeen lessons stay unstable.
The difference between [ and [[, the trap waiting in while read when you go through a file line by line, and how far a variable leaks when you forget local. You meet the shell's "wrong but it still ran" cases first.
The routes by which values reach a script from outside. Parsing options with getopts, using parameter expansion instead of calling an external command, arrays and associative arrays, and here documents.
Opening file descriptors yourself, choosing between grep, sed and awk, cleaning up with mktemp and trap, designing logs, and stopping a second copy from starting. This is the chapter for scripts that run for a long time.
Let machines read it with ShellCheck and shfmt, write tests with bats, check portability against dash, trace slowness back to subshells, and finally put it on a schedule with cron and a systemd timer.
Once you have finished all 20 lessons, turn to the servers your scripts will run on. Linux System Administration takes you into systemd and logs. If the commands themselves still feel shaky, go to Linux for Beginners. Membership unlocks every course.