How do I get a bash script to echo itself into a new file? [closed]

I have a bash script. I want to have this script recreate itself in /usr/local/bin without needing an additional file to do this.

bash_a.sh:

ssh -t -t server-a.com "
cd /var/
irb
..etc
"

I was thinking something along the lines:

echo "
ssh -t -t server-a.com "
cd /var/
irb
..etc
"
" > /usr/local/bin/bash_a.sh

Or this:

cp bash_a.sh /usr/local/bin/bash_a.sh
ssh -t -t server-a.com "
cd /var/
irb
..etc
"
1

2 Answers

Try the single-quotes and double-quotes trick for your suggestion:

echo '#!/bin/bash
ssh -t -t server-a.com "
cd /var/
irb
..etc
"
' > /usr/local/bin/bash_a.sh
chmod a+rx /usr/local/bin/bash_a.sh

Inside single quotes, the shell handles the data unchanged. Inside double quotes, the shell expands $variables, backslash, backticks and all sorts of stuff. So generally use single quotes where possible.

However, inside single quotes you can't use single quotes easily, whereas double quotes inside single quotes is easy.

Inside double quotes you can use double quotes, but you must escape them with backslash. So echo "abc\"def\"" prints abc"def".

Inside double quotes you can use single quotes too, but they dont stop all that expansion. So echo "abc'def'" prints abc'def'.

You can use single quotes inside single quotes but you have to type:echo 'abc'\''def'\''hij' which prints abc'def'hij.

Using the answer in Can a Bash script tell what directory it's stored in?:

#!/bin/bash
DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
BINDIR=/usr/local/bin
if [[ $DIR != $BINDIR && -w $BINDIR ]]
then cp "${BASH_SOURCE[0]}" $BINDIR
fi
... rest of script

The if prevents the script from trying to copy itself it's being run from /usr/local/bin, or if it's being run by a user who doesn't have permission to copy there.

You Might Also Like