I tried to run commands using pipes.
Basic:
single=\"ls -l\"
$single
which works as expected
Pipes
You're demonstrating the difference between the shell and the kernel.
"ls -l" is executable by the system execve() call. You can man execve
for details, but that's probably too much detail for you.
"ls -l | grep e" needs shell interpretation to set up the pipe. Without using a shell, the '|' character is just passed into execve() as an argument to ls. This is why you see the "No such file or directory" errors.
Solution:
cmd="ls -l | grep e"
bash -c "$cmd"