为什么~
不展开呢$ ./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
同时存在空格和符号,那么如何编写脚本?~
添加2:当我尝试mkdir
不带引号的路径不带空格时:
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
才会在bash
, dash
, mksh
and中扩展波浪号yash
。ksh93
还将在$a
、和zsh
中扩展它。$a
$b
根据 POSIX标准(强调我的):
“波形符前缀”由
<tilde>
单词开头的未加引号的字符组成,后跟该单词之前的所有字符第一个未引用的<slash>
在这个词中。在赋值中,可以使用多个波浪号前缀:在单词的开头(即,在赋值的等号之后),在任何不带引号的冒号之后,或两者都使用。赋值中的波形符前缀以以下方式终止第一个不带引号的冒号或斜杠。
恕我直言,这只是一个毫无意义的烦恼,因为尽管不符合其字母,但它只是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