0

I've used printf but it takes variables from the file itself. I would like to copy all the code without any changes to a new_file.

printf "${name}_delete()
  {
    bhyvectl --vm=${name} --destroy
    sleep 5
    ifconfig ${tap} destroy
    sysrc cloned_interfaces-=${tap}
    sed -i '' 's/ addm ${tap}//g' /etc/rc.conf
    sed -i '' 's/service ${name} start | sleep 5//g' /usr/local/etc/rc.d/bhyve
    sed -i '' '/^$/d' /usr/local/etc/rc.d/bhyve
    zfs destroy -r zroot/VMs/${name}
    rm /usr/local/etc/rc.d/${name}
  }\n" >> new_file
Amr
  • 61
  • 4
  • Variables will be expanded inside double quotes - you can use single quotes to prevent that (although that will complicate the single-quoted strings elsewhere) or use a *here document*. See related [How do I append multiple lines involving variables to the end of a bash script?](https://unix.stackexchange.com/questions/238881/how-do-i-append-multiple-lines-involving-variables-to-the-end-of-a-bash-script) – steeldriver Dec 26 '20 at 17:45
  • I've used single quotes but it's not working because of sed command – Amr Dec 26 '20 at 17:48

1 Answers1

2

I believe the best tool for doing this would be to use cat with a quoted here-document:

cat <<'END_SCRIPT' >>new_file
${name}_delete()
{

    bhyvectl --vm=${name} --destroy
    sleep 5
    ifconfig ${tap} destroy
    sysrc cloned_interfaces-=${tap}
    sed -i '' 's/ addm ${tap}//g' /etc/rc.conf
    sed -i '' 's/service ${name} start | sleep 5//g' /usr/local/etc/rc.d/bhyve
    sed -i '' '/^$/d' /usr/local/etc/rc.d/bhyve
    zfs destroy -r zroot/VMs/${name}
    rm /usr/local/etc/rc.d/${name}
}
END_SCRIPT

This would append the contents of the here-document, as it is, without substituting the values for any variables or doing any other expansions, to the end of the fie new_file.

It's the quoting around the initial END_SCRIPT delimiter that makes this a quoted here-document. The string END_SCRIPT is an arbitrary string, but it makes sense to choose this so that it is somewhat descriptive (just like you choose descriptive variable names).

Note that the script that you are outputting contains unquoted variable expansions and other errors. Correcting this:

cat <<'END_SCRIPT' >>new_file
${name}_delete ()
{

    bhyvectl --vm="$name" --destroy
    sleep 5
    ifconfig "$tap" destroy
    sysrc cloned_interfaces-="$tap"
    sed -i '' "s/ addm $tap//g" /etc/rc.conf
    sed -i '' "s/service $name start | sleep 5//g" /usr/local/etc/rc.d/bhyve
    sed -i '' '/^$/d' /usr/local/etc/rc.d/bhyve
    zfs destroy -r "zroot/VMs/$name"
    rm "/usr/local/etc/rc.d/$name"
}
END_SCRIPT

I've assumed that you want to expand the variables tap and name in the two calls to sed when the embedded script runs. I have removed unnecessary curly braces around variable names, and I've added appropriate double quotes.

Kusalananda
  • 320,670
  • 36
  • 633
  • 936