1

I have a script that inputs 2 -> file#.txt -> newline into my program. However, the script only inputs file4.txt into my program, even though the loop is running 10 times. I'm not sure why this is happening specifically for i=4.

gnome-terminal --working-directory=/path/to/dir/ -- bash -c "{ for i in {1..10}; 
  do echo "2"; echo "file"$i".txt"; echo $'\n'; done; } | ./program; exec bash"
MoeMan
  • 49
  • 4

1 Answers1

2

The $ characters are being processed by your original shell, not the shell executed inside gnome-terminal. Also, the embedded double quotes are delimiting the -c argument, not being passed explicitly to bash.

You need to escape the $ and " characters to preserve them.

gnome-terminal --working-directory=/path/to/dir/ -- bash -c "{ for i in {1..10}; 
  do echo \"2\"; echo \"file\"\$i".txt\"; echo \$'\n'; done; } | ./program; exec bash"

You could also put the command in single quotes, but then you won't be able to embed $'\n' in it, because you can't escape quotes inside single quotes. But you can use printf instead of echo, since it will translate escape sequences itself.

gnome-terminal --working-directory=/path/to/dir/ -- bash -c '{ for i in {1..10}; 
  do echo "2"; printf "file%d.txt\n\n" $i; done; } | ./program; exec bash'

See Difference between single and double quotes in Bash

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • 2
    Or just `printf "2\nfile%d.txt\n\n" {1..10}` instead of a loop. – Shawn Apr 08 '21 at 22:55
  • @Shawn I suspect this is a simplification, and the real application may want to do more inside the loop, since this is simply printing a fixed string. – Barmar Apr 08 '21 at 22:57
  • @Barmar What would I need to change if I want to pass command line arguments to my program like `./program $C1 $C2; exec bash`. I had some arguments that I was passing into my program with the old command which doesn't work with the new single quotes command that I'm now using. – MoeMan Apr 08 '21 at 23:31
  • A better approach in general would be to put everything in a script file and invoke that, rather than trying to cram it into a `bash -c` line. – Barmar Apr 09 '21 at 13:00