0

I am attempting to create a bash script that will allow me to install the same bash function across multiple machines. This particular function creates a copy of a file with a timestamp in a backup directory:

filebackup () { cp "${@}" ~/"filebackup/${@}_$(date +%Y-%m-%d_%H:%M:%S).bk"; }

Here is my bash script:

cat <<EOT >> ~/.bashrc
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

# create a file backup in ~/filebackup/ with timestamp
filebackup () { cp "${@}" ~/"filebackup/${@}_$(date +%Y-%m-%d_%H:%M:%S).bk"; }
EOT

source ~/.bashrc

When I execute the script, however, the ${@} are missing and the $(date +%Y-%m-%d_%H:%M:%S) has been evaluated. Here is what has been appended to the .bashrc file:

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

# create a file backup in ~/filebackup/ with timestamp
filebackup () { cp "" ~/"filebackup/_2017-01-05_12:07:56.bk"; }

How can I ensure that the function is copied literally into the file?

Alex Willison
  • 257
  • 7
  • 20
  • Quote `"EOT"` on line 1 (but not on line 6). – that other guy Jan 05 '17 at 17:15
  • @thatotherguy *Pushes Easy Button*. _That was easy!_ Thanks! – Alex Willison Jan 05 '17 at 17:18
  • @DanFarrell I feel that I was pretty thorough in my search for similar questions... as a newer user, the terminology in the other question is not something I am familiar with and therefore would never have found it! – Alex Willison Jan 05 '17 at 17:21
  • That's OK @AlexWillison, a vote to close isn't a downvote. This question is, however, a duplicate. – erik258 Jan 05 '17 at 17:22
  • AlexWillison Perfectly ok. It's really hard to find duplicates because both google and stackoverflow are bad at searching for symbols, and you basically have to know what the answer is to find a duplicate question :P – that other guy Jan 05 '17 at 17:30

2 Answers2

2

A here document is treated as a double-quoted string, so parameter expansions and command substitutions are evaluated before the command reads from them. Quote any part of the delimiter to have the here document treated as a single-quoted string.

cat <<\EOT >> ~/.bashrc
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

# create a file backup in ~/filebackup/ with timestamp
filebackup () { cp "${@}" ~/"filebackup/${@}_$(date +%Y-%m-%d_%H:%M:%S).bk"; }
EOT

By any part, I mean any of the following would work just as well:

  • 'EOT'
  • E\OT
  • "E"OT

et cetera.

chepner
  • 497,756
  • 71
  • 530
  • 681
0

Suggested by @thatotherguy in a comment: quote "EOT" on line 1 (but not on line 6).

cat <<"EOT" >> ~/.bashrc
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

# create a file backup in ~/filebackup/ with timestamp
filebackup () { cp "${@}" ~/"filebackup/${@}_$(date +%Y-%m-%d_%H:%M:%S).bk"; }


EOT

source ~/.bashrc
Alex Willison
  • 257
  • 7
  • 20