I'm trying to create next script

echo "#!/bin/sh" >/script
echo "del x.txt" >>/script

witch is ok if /script file is empty, if not - will append first line to last text

del x.txt#!/bin/sh
del x.txt

If I add an echo empty line first it's ok again if file not empty, but if empty - the script will not be executed

echo "" >>/script
echo "#!/bin/sh" >>/script
echo "del x.txt" >>/script


I will explain exactly what I'm trying to do, on my asuswrt router I want to add a new rule to port forwarding script, witch is firewall-start

echo "#!/bin/sh" >/jffs/scripts/firewall-start
echo "" >>/jffs/scripts/firewall-start
echo "iptables -I INPUT -p tcp --destination-port 3000 -j ACCEPT" >>/jffs/scripts/firewall-start

This will overwrite any text in /jffs/scripts/firewall-start

I want a solution to create script from scratch or to append this lines but starting with new line and not to append text to the last line. If I start with empty line and the script is empty, will not be executed after because #!/bin/sh should be in the first line

echo "" >>/jffs/scripts/firewall-start
echo "#!/bin/sh" >/jffs/scripts/firewall-start
echo "" >>/jffs/scripts/firewall-start
echo "iptables -I INPUT -p tcp --destination-port 3000 -j ACCEPT"


  • What you're describing should not be happening. If you say echo "#!/bin/sh" >/script again, it will wipe out everything already in the script. If you say echo "#!/bin/sh" >>/script, it should go on a new line, unless you did something weird to cause the del x.txt line to not end with a newline. – Scott Oct 30 '14 at 20:06
  • echo even without arguments produce newline. Try echo text | hd -c – Costas Oct 30 '14 at 21:05

You can test to see if a file is empty by using unix test -s. Example below...

 if [ -s $file ]
   echo "File size is zero"
   echo "File size is not zero"

I have try to re-produce the case and have found that in case where the last line in the file don't finish with newline (where can happend for example if echo -n '#!/bin/bash' > /script used) the operation echo "del x.txt" >>/script can produce

cat /script
#!/bin/bashdel x.txt

To avoid this you can use sed instead echo

sed -i '$a\del x.txt' /script

-i --in-place input file modification

$ mean last line

a append command

  • Yes but this will not create the file if doesn't exist – Gigi Duru Oct 31 '14 at 18:13
  • @GigiDuru you can use touch /script to make a new file if it did not exist or just change the modification time if have exist. – Costas Oct 31 '14 at 21:09

You can get the first line from a file like:

read -r varname <file

In the case where a file contains less than one \newline - or if the file does not exist, or can otherwise not be read - the above command will return other than 0. Else it will return 0 and $varname will contain the file's first line.

In fact, if the file cannot be read for any reason the redirection <doesntexist will very likely kill a scripted shell because the < syntax is an operator and not a command. However, command <doesntexist will negate this behavior and demotes the status of the <operator to a reliably testable condition.

And so, you can do:

command read -r line1 <file && 
echo delx.txt >> file    ||
printf %s\\n '#!/bin/sh' "# $line1" delx.txt >file

Which would append to a file containing a \newline or insert a hashbang at the head of a truncated file that afterward contains the commented previous contents (if anything at all and sans NUL bytes) of file, then a \newline, and last the string delx.txt followed by another \newline.

Either it would contain those things or the script really does fail on either the echo or printf line because the file you are trying to write to is not writable by you - which is probably a good thing.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.