3

I want to insert this

cat <<EOF >> /etc/security/limits.conf
*    soft     nproc       65535    
*    hard     nproc       65535   
*    soft     nofile      65535   
*    hard     nofile      65535
root soft     nproc       65535
root hard     nproc       65535
root soft     nofile      65535
root hard     nofile      65535
EOF

into the second to last line of the file, before the # End of file line.

I know I could use other methods to insert this statement without the use of EOF but for visual candy I wanted to maintain this format as well for readability.

  • The method above just appends to file. So without a tool that can recognize the # End of file line there's probably no better way to make it work. Such tool would be either awk or sed. I'd recommend a 2 step process: delete the line via sed -i '/# End of file/d' and then insert the data you want with # End of file added to original cat command you have there, or via third step - echo '# End of file' >> /etc/security/limits.conf. – Sergiy Kolodyazhnyy Mar 2 at 2:10
  • Let me know if you want that as an answer and not just comment – Sergiy Kolodyazhnyy Mar 2 at 2:11
  • I'm unclear on the requirements: do you want to insert all 10 lines into some other undisclosed file? Or are you saying that you want to append the 8 lines of data into the limits.conf file, but just not at the end of that file? – glenn jackman Mar 2 at 18:29
5

You can use ex (which is a mode of the vi editor) to accomplish this.

You can use the :read command to insert the contents into the file. That command takes a filename, but you can use the /dev/stdin pseudo-device to read from standard input, which allows you to use a <<EOF marker.

The :read command also takes a range, and you can use the $- symbol, which breaks down into $, which indicates the last line of the file, and - to subtract one from it, getting to the second to last line of the file. (You could use $-1 as well.)

Putting it all together:

$ ex -s /etc/security/limits.conf -c '$-r /dev/stdin' -c 'wq' <<EOF
*    soft     nproc       65535    
*    hard     nproc       65535   
*    soft     nofile      65535   
*    hard     nofile      65535
root soft     nproc       65535
root hard     nproc       65535
root soft     nofile      65535
root hard     nofile      65535
EOF

The -s is to make it silent (not switch into visual mode, which would make the screen blink.) The $-r is abbreviated (a full $-1read would have worked as well) and finally the wq is how you write and quit in vi. :-)


UPDATE: If instead of inserting before the last line, you want to insert before a line with specific contents (such as "# End of file"), then just use a /search/ pattern to do so.

For example:

$ ex -s /etc/security/limits.conf -c '/^# End of file/-1r /dev/stdin' -c 'wq' <<EOF
...
EOF
7

To keep the same sort of here-document format and to insert the given text immediately before the last line of the file, try ed!

ed -s /etc/security/limits.conf << EOF
$ i
*    soft     nproc       65535    
*    hard     nproc       65535   
*    soft     nofile      65535   
*    hard     nofile      65535
root soft     nproc       65535
root hard     nproc       65535
root soft     nofile      65535
root hard     nofile      65535
.
wq
EOF

This sends a sequence of commands to ed, all in a here-document. We address the last line in the file with $ and say that we would like to insert some text. The text follows, just as in your example; once we're done with the inserted text, we tell ed we're done with a single period (.). Write the file back to disk and then quit.

If you wanted to collapse the $ i to $i you'd want to escape the dollar sign or use a quoted here-document (ed -s input << 'EOF' ...) to prevent $i from expanding to the current vale of the i variable or empty if there's no such variable set.

0

Another method: print all but the last line of the file, print the new text, then print the last line of the file. Then redirect all that output to a new file.

{
    sed '$d' limits.conf
    cat <<EOF
*    soft     nproc       65535
*    hard     nproc       65535
*    soft     nofile      65535
*    hard     nofile      65535
root soft     nproc       65535
root hard     nproc       65535
root soft     nofile      65535
root hard     nofile      65535
EOF
    tail -1 limits.conf
} > tmpfile && mv tmpfile limits.conf

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.