パス変数に「〜」などのスペースと記号の両方を含めるには、bashでスクリプトをどのように作成しますか?

パス変数に「〜」などのスペースと記号の両方を含めるには、bashでスクリプトをどのように作成しますか?

なぜ~それを拡張しないのです$ ./foo.shか?

MYPATH_TO=~"/Documents 2/temp"
echo ~
echo "$MYPATH_TO"
mkdir "$MYPATH_TO"

実行時に/home/mint/Documents 2生成されます/home/mint/Documents 2/~/Documents 2/temp(エコー出力/home/mint ~/Documents 2/temp)。私が読んで二重引用符の中でチルダ(〜)が拡張されないのはなぜですか?~そして、引用符の外側に置いても、まだ展開されません。なぜですか?

追加:引用されているため拡張されませんが、mkdirパスにスペースと記号の両方があると予想される場合は、どのようにスクリプトを作成できますか?~

mkdir追加2:スペースなしで引用符で囲まれていないパスを試みるとき:

MYPATH_TO=~"/Documents/temp"
mkdir $MYPATH_TO

エラーが発生しますmkdir: cannot create directory ‘~/Documents/temp’: No such file or directory。なぜ?Documents家にいます。私は迷子になりました...

システム:Linux Mint 19.2

答え1

クイック修正は、引用された部分の外側に最初のスラッシュを置くことです。

MYPATH_TO=~/"Documents 2/temp"
echo "$MYPATH_TO"

/home/user/Documents 2/temp

他の例:

bash -c 'a=~"/." b=~\/. c=~/. d=~/"."; echo "$a $b $c $d"'
~/. ~/. /home/user/. /home/user/.

$cとのみ、およびでチルダを展開$dします。また、およびでも拡張される予定です。bashdashmkshyashksh93$azsh$a$b

POSIXによると基準(強調):

「チルダプレフィックス」は、<tilde>単語の先頭に引用符がない文字と、その単語の前のすべての文字で構成されます。初めて引用しなかった<slash>この言葉に。割り当てでは、複数のチルダプレフィックスを使用できます。単語の先頭(たとえば、割り当ての等号の後)、引用符のないコロンの後、またはその両方。割り当てのチルダプレフィックスは、次のように終了します。引用符のない最初のコロンまたはスラッシュ

IMHO、これは文字に従わないにもかかわらず、ksh93ユーザー名にスラッシュを含めることを意図しているように見えることを達成するので、無意味な迷惑に過ぎません(からバックティックを使用してエスケープできますksh93)。

cat <<'EOT' >getpwnam.c
#include <pwd.h>
static struct passwd pwd = { "", "", 666, 666, "", "/hell", "" };
struct passwd *getpwnam(const char *name){ return &pwd; }
EOT
cc -Wall -shared getpwnam.c -o getpwnam.so
for sh in dash bash yash mksh zsh ksh93; do
    printf '%s\t' "$sh"
    LD_PRELOAD=./getpwnam.so HOME=nowhere \
      "$sh" -c 'echo ~q ~\/q ~"/q"'
done

dash    /hell ~/q ~/q
bash    /hell ~/q ~/q
yash    /hell ~/q ~/q
mksh    /hell ~/q ~/q
zsh     /hell nowhere/q nowhere/q
ksh93   /hell /hell nowhere/q

関連情報