I can run this loop directly and it lists the files in the current directory:
for i in *; do echo "$i"; done
However, trying to run it as `bash for i in *; do echo "$i"; done` produces a syntax error near `do`. I also want to run the loop through `bash -c` or as an administrator with `sudo`. What quoting or escaping is required, and why does invoking Bash this way change the behavior?
3 Answers
`bash for i in ...` does not treat the text as a command to interpret. Bash sees `for` as the name of a script or file and the remaining words as arguments. To pass a command string to a new Bash process, use `-c` and quote the entire loop: `bash -c 'for i in *; do echo "$i"; done'`. The quotes keep the loop together as one argument and prevent the current shell from expanding `*` first.
If you only want a subshell, you do not need to start another Bash process. Group the loop in parentheses: `( for i in *; do echo "$i"; done )`. This runs it in a subshell environment. Also, quote `"$i"` so filenames containing spaces or wildcard characters are handled safely.
For an administrator shell, put the complete command after `sudo bash -c` and quote it as one argument: `sudo bash -c 'for i in *; do echo "$i"; done'`. Without the quotes, the outer shell splits the loop into separate arguments before Bash receives it, so the syntax is no longer a single script.

Related Questions
Can't Load PhpMyadmin On After Server Update
Redirect www to non-www in Apache Conf
How To Check If Your SSL Cert Is SHA 1
Windows TrackPad Gestures