~ を含むパスを変数に保存するにはどうすればいいですか?

~ を含むパスを変数に保存するにはどうすればいいですか?

スクリプトには次の変数があります:

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

varTARGET_DIRにこのパスを保持させ、の代わりに/home/username/.sshを使用します。しかし、スクリプトを実行してユーザー名の下に新しいディレクトリを作成しようとすると、次のメッセージが表示されます。~/home/.ssh

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

/home/username ディレクトリが存在するにもかかわらず、これを実行すると 動作します。変数で符号をTARGET_DIR="/home/${TARGET}/.ssh" 使用するにはどうすればよいですか?~

答え1

ではbash、、チルダ展開ashはパラメータ展開の前に行われるため、機能しません。mkshyash

ksh93ここでは代わりにまたは を使用するzshか、 を使用することもできますeval

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

システムにgetentコマンドがある場合 (最近ではかなり一般的です)、次のコマンドも使用できます。

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

または以下を使用しますperl:

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

これは、ユーザー名に珍しい文字 (zsh では問題になる~$userksh93's~"$user"では問題にならないスペースなど) が含まれるユーザーにも機能します。

関連情報