If HOME variable is set, ~ in your example expands according to the variable. Normally the variable is exported to the environment.
From man 8 sudo:
-E
The -E (preserve environment) option indicates to the security policy that the user wishes to preserve their existing environment variables. The security policy may return an error if the -E option is specified and the user does not have permission to preserve the environment.
So sudo -E your_script is a way to have ~/.bashrc in the script expanded to /home/actual_user/.bashrc. Note environment variables other than HOME will also be preserved.
Alternatively you can preserve just this one variable with
sudo HOME="$HOME" your_script
This works out of the box in my Debian but please see man 8 sudo and man 5 sudoers to learn how variables may be restricted.
Another alternative is to set the variable at the beginning of your script. Its value may be hardcoded or passed as a command line argument.
Be aware that running your entire script with sudo has disadvantages:
- Any bug will bite you with elevated permissions.
- If your script needs to know the actual user's
$HOME in order to create files or directories therein, then the objects created will be owned by root. This may be a problem later on, when you want to use them without sudo. The general premise is everything in your home directory is yours (possible exceptions are, well, exceptions).
Maybe you can isolate the elevated part of the script, so it runs in its entirety after you provide the password once, then returns to the non-elevated parent script to mangle with /home/actual_user. Like this:
#!/bin/bash foo1 # runs normally sudo bash <<EOF bar1 # runs as if with sudo bar2 # runs as if with sudo EOF foo2 # runs normally