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?

1
  • ~ 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" Nov 22, 2017 at 16:20

1 Answer 1

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).

2
  • 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, 2017 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)). Nov 23, 2017 at 9:29

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .