Closed aryarm closed 5 years ago
It might be hard to find a portable way of prepending the text without creating a temporary file. Oh, how I love bash
sources: some recommendations for prepending text and a discussion about portability
What? could have sworn sed could handle this, it's a text editor like any other
yeah, but sed -i
isn't very portable, apparently
we can use sed -i
's backup file feature: sed -i.bak -e '…' SOMEFILE
as described in this stack overflow post but this won't work on some systems (ex: BusyBox) and isn't really in POSIX and apparently there are sometimes problems with permissions on the files?
Wait, so are we not supposed to use sed or just one particular feature?
just sed -i
, I think
I know this is an old issue but I kept it in the back of my mind. How's this for a one-line, portable solution?!
echo "$(echo "prepend me" | cat - .bash_aliases)" > .bash_aliases
The subshell forces bash to execute the cat
before setting up the redirect into the file (source). Using cat -
will force cat
to accept input from stdin, so we can use it to concatenate stdin with the .bash_aliases
file. A variable could also be used in place of the string.
It seems better than the solutions on StackOverflow, at least. We don't use temporary files and it's completely portable to my knowledge.
I suppose you could also use process substitution instead of the pipe. But process substitution is a bashism, so it's not portable.
echo "$(cat <(echo "prepend me") .bash_aliases)" > .bash_aliases
Alternatively, you could use a here-string instead of using echo
. But again, here-strings are a bashism, so it's not portable. One benefit to this method over the other two, however, is that it doesn't create any nested subshells:
echo "$(cat - .bash_aliases <<< "prepend me")" > .bash_aliases
Fun fact that I recently discovered:
Running cat
without specifying its input will cause it to block and read input from the terminal (until you press Ctrl+D). Here's an example where someone used it to append arbitrary text to a file.
Turns out you can prepend arbitrary text to a file using this method, too :D
echo "$(cat - filename)" > filename
It might be better for
setup
to prepend the code that includes.included
, instead of appending it. That way, other aliases and things that are defined in the user's.bash_aliases
will be given priority over our own. This will also allow people to build their own aliases over our own (or generally write any code that depends on ours).