As pointed out in the answer you have to first make a 1200bit/s connection and then disconnect, but the answer doesn't explain how to do this.
What I did was first uploaded a dummy program to my Leonardo in the Arduino IDE, making sure "verbose" mode was enabled for uploading in File -> Preferences. By "dummy" program I just mean anything that will successfully upload, let's say a program that is nothing but an empty setup() and loop() function.
Then scroll through the log and find the command it uses to upload.
Then create an "upload.sh" file and paste in that command, changing the ".hex" file to the file you want to upload.
Finally, add another line to the top of the file for making the temporary 1200bit/s connection, so when you run the script it will make the connection then immediately upload your file.
My script ended up looking something like this.
device=ACM0
stty -F /dev/tty$device 1200 cs8 -cstopb -parenb && echo -ne '\x00' > /dev/tty$device && sleep 1 && stty -F /dev/tty$device 0
"/home/primary/.arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/bin/avrdude" "-C/home/primary/.arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/etc/avrdude.conf" -v -V -patmega32u4 -cavr109 "-P/dev/ttyACM0" -b57600 -D "-Uflash:w:p4s.hex:i"
This worked successfully for me to send the "p4s.hex" file.
Change "device" to the tty device you're using and again the last line is copied from whatever your Arduino IDE is doing. It should already have the correct device name.
The first two lines again are just for making the temporary 1200bit/s connection and then immediately disconnecting.