1

I'm having a difficulty writing a command in a file using a bash script (NOT the output of the command + I don't want the command to be executed) I want the file to simply have run $(python -c "print('A'*256)") inside of it.

I've tried adding it in a variable then passing it to a file by echo, that didn't work.

I also tried something like echo "run $(python -c "print('A'*256)")" > file.txt

Also didn't work, I actually got some errors so I assumed that the problem is because of the multiple double quotations, so I changed them to single quotations. That gave me this output in the file run

So it basically ignored $(python -c "print('A'*256)") completely.

Any idea how to resolve this?

Jack
  • 11

3 Answers3

3

The most reliable way to get arbitrary strings into redirections is to use a here document:

cat > file.txt <<'EOT'
run $(python -c "print('A'*256)")
EOT

This will put that single line exactly as-is into file.txt. The text up until EOT is given to cat as its standard input, and cat just spits it out again to be redirected. The shell will keep reading the document until EOT appears at the start of the line, so you could put multiple lines in at once if you wanted (if EOT appears like that within your string, use something else instead - the delimiter is arbitrary).

Because the delimiter is quoted at the top, no expansions are performed on the body of the here-document1 and all your characters are passed through untouched. The behaviour of here-documents is specified by POSIX and will work in any shell.

1There was a bug in some older versions of Bash that did perform some expansions in certain cases, but you won't hit that here.

Michael Homer
  • 76,565
0

A string with *both kinds of quotes in it is always hard to handle.  There are three approaches:

  • Alternate between the two kinds of quotes.  Put the double quotes (") inside single quotes (') and vice versa.

    First break your string into three pieces:

    run $(python -c "print ('A'*256) ")
    ↑---------1----------↑ ↑---2---↑ ↑3↑
    

    where the first and third part contain no single quotes, and the second part has no double quotes.  Then quote them appropriately:

    echo 'run $(python -c "print'"('A'*256)"'")'
         ↑----------1-----------↑↑----2----↑↑-3↑
    

    just running the substrings together.

  • Quote the string with double quotes, and then use \" for every literal double quote that you want to have echoed.  Also replace $ with \$

    echo "run \$(python -c \"print('A'*256)\")"
    
  • An approach that works in bash only is to quote the string with $'…'.  Inside such a string, you can escape single quotes with \':

    echo $'run $(python -c "print(\'A\'*256)")'
    

Of course the > file.txt part is as you would expect.

0

Try to use escape characters instead:

echo run \$\(python -c \"print\(\'A\'*256\)\"\) > file.txt