1

I have these variables in my script:

TARGET=username
TARGET_DIR="~${TARGET}/.ssh"

I want the TARGET_DIR var to hold this path: /home/username/.ssh but to use ~ instead of /home/. But when I run the script and try to make new .ssh dir under username it tells me:

mkdir: cannot create directory ‘~username/.ssh’: No such file or directory

Even though the /home/username dirs exists. If I do: TARGET_DIR="/home/${TARGET}/.ssh" it works. How can I use the ~ sign in the variable?

  • ~ will refer to the users home directory i.e. /home/username. You would therefore not need to expand ~ but rather add home to TARGET_DIR so TARGET_DIR="/home/$TARGET/.ssh" – Raman Sailopal Nov 22 '17 at 16:20
3

In bash, ash, mksh and yash tilde expansion occurs before parameter expansion, so that can't work.

You can use ksh93 or zsh instead here, or resort to eval:

user=username # making sure it's a valid username
eval "user_home=~$user"
target_dir=$user_home/.ssh

If your system has a getent command (quite common nowadays), you can also use:

user_home=$(getent -- passwd "$user" | cut -d: -f6)

Or use perl:

user_home=$(perl -le 'for (@ARGV) {
  @u = getpwnam$_ or die "No such user: $_\n";
  print $u[7]}' -- "$user")

Which would also work with users with uncommon characters in their username (like space which zsh's ~$user but not ksh93's ~"$user" would also have a problem with).

  • thanks, but didn't you meant the other way? That param expansion happens before the ~ expansion? Otherwise, it makes no sense to me. I would like if you can clarify that for me, please. – lakerda Nov 23 '17 at 8:48
  • @lakerda, no. If param expansion happened before, then ~$user would be expanded to ~username and then to /home/userhome. But it's the other way round. If you had a user whose username was $user, ~$user would expand to the home directory of that user (in bash, not in ash/mksh/yash where that ~$user is simply not recognised as a tilde expansion at all as they consider $ is not a valid character in a user name. As currently written, the POSIX spec would imply that only bash is conformant in that regard (but not conformant in others, the POSIX spec is not clear)). – Stéphane Chazelas Nov 23 '17 at 9:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.