Em bash , ash , mksh e yash tilde, a expansão ocorre antes da expansão do parâmetro, portanto isso não funciona.
Você pode usar ksh93 ou zsh aqui ou recorrer a eval :
user=username # making sure it's a valid username
eval "user_home=~$user"
target_dir=$user_home/.ssh
Se o seu sistema possui um comando getent (bastante comum hoje em dia), você também pode usar:
user_home=$(getent -- passwd "$user" | cut -d: -f6)
Ou use perl :
user_home=$(perl -le 'for (@ARGV) {
@u = getpwnam$_ or die "No such user: $_\n";
print $u[7]}' -- "$user")
O que também funcionaria com usuários com caracteres incomuns em seu nome de usuário (como o espaço em que zshs ~$user , mas não ksh93 ' ~"$user" também teriam um problema).