I want to loop over the entries in a directory and work with just their names rather than full relative paths. I tried `for file in $(ls folder)`, but command substitution hides the failure when the directory does not exist and it also breaks on unusual filenames. A glob such as `folder/*` is safer, but it expands to paths, so I would need to strip the directory with `basename`. Is there a direct shell or parameter-expansion approach for this? Also, can I configure options such as `shopt -s failglob` and `set -o pipefail` in one startup file so every Bash script gets them automatically?
3 Answers
You can also change into the target directory and glob there: `for name in folder/*; do ...; done` is usually fine if you keep the path and use `${name##*/}` when displaying or processing only the basename. If you need robust handling of every possible filename, including newlines, use null-delimited output from `find` with `-print0` and read it with `readarray` or a `while IFS= read -r -d ''` loop.
There is a `BASH_ENV` mechanism for non-interactive Bash shells, and it can point to a file containing startup commands. However, relying on global shell state is generally a bad idea: options such as `failglob` and `pipefail` can change how unrelated scripts behave. Each script should enable the options it depends on near the top, for example `set -o pipefail` and the relevant `shopt` settings.
That also makes scripts predictable when they are run by cron, another program, or a different user environment. Treat shell options as part of the script's own configuration rather than assuming a profile file was loaded.
A glob naturally expands to paths, but Bash parameter expansion can remove the directory portion without starting `basename`: `for path in folder/*; do name=${path##*/}; printf '%sn' "$name"; done`. If you want the loop to do nothing when there are no matches, enable `nullglob` first: `shopt -s nullglob`. Alternatively, check the directory with `[[ -d folder ]]` before looping. Avoid parsing `ls`, since command substitution and whitespace splitting do not handle arbitrary filenames safely.

For ordinary scripts, a direct glob is much simpler than `find`; `find` becomes useful when you need recursion, file-type filtering, or null-delimited processing.