With your command as shown, neither ls not cat is actually executed:
$ for qw in `cat foo.txt`; do echo $qw; done
/bin/ls
/bin/cat /etc/redhat-release
To get the output that you show, I suspect that you actually ran this command;
$ for qw in `cat foo.txt`; do $qw; done
foo.txt
bash: /bin/cat /etc/redhat-release: No such file or directory
In this case, ls is executed but /bin/cat /etc/redhat-release is not executed because there is no command whose name is the full string /bin/cat /etc/redhat-release. (The shell does not do word-splitting here.)
To see this in a simpler example:
$ ls *.txt
foo.txt
$ a="ls *.txt"; $a
bash: ls *.txt: command not found
Executing all the commands and capturing output to file
To execute all the command in foo.txt, run:
$ bash foo.txt
foo.txt
CentOS release 6.6 (Final)
To run all the commands and capture their output to file output.log, then run:
bash foo.txt >output.log
To run all the commands and show their output on screen while also capturing the output to a file:
$ bash foo.txt | tee output.log
foo.txt
CentOS release 6.6 (Final)
Capturing each command's output to a different file
First, run awk on foo.txt to create foo.sh:
$ awk '{sub(/$/, (" >output" ++count))} 1' foo.txt >foo.sh
This is what foo.sh looks like:
$ cat foo.sh
/bin/ls >output1
/bin/cat /etc/redhat-release >output2
As you can see, each command in the file now has its stdout sent to a numbered file. If you want to capture stderr as well, that is just a small change.
Now, run foo.sh:
$ bash foo.sh
$ cat output1
foo.sh
foo.txt
output1