为什么 cp 检测不到‘\’(反斜杠+空格)?

为什么 cp 检测不到‘\’(反斜杠+空格)?

我试图编写一个 shell 脚本来复制文件。以下是我所做的。

 workingDirectory=$(pwd | sed "s/ /\\ /g")

现在echo $workingDirectory显示/home/user/Documents/Learning and Development/

但我知道,为了让cp命令正常工作,我需要用\(反斜杠+空格)替换空格。所以我sed稍微修改了命令,如下:

workingDirectory=$(pwd | sed "s/ /\\\ /g")

如此看来,echo $workingDirectory一切/home/user/Documents/Learning\ and\ Development/都很好。

但是当尝试使用cp命令时,

cp $workingDirectory/jad/jad /usr/bin/

我收到错误,

cp: cannot stat ‘/home/user/Documents/Learning\\’: No such file or directory
cp: cannot stat ‘and\\’: No such file or directory
cp: cannot stat ‘Development/jad/jad’: No such file or directory

这可能是什么原因?如何解决?

编辑

如果我使用第一个sed命令,那么错误是

cp: cannot stat ‘/home/user/Documents/Learning’: No such file or directory
cp: cannot stat ‘and’: No such file or directory
cp: cannot stat ‘Development/jad/jad’: No such file or directory

答案1

转义变量内的字段分隔符来防止单词拆分是没有用的:shell 仍然会根据列出的分隔符​​拆分单词$IFS

~/tmp/directory with spaces$ workingDirectory=$(pwd | sed "s/ /\\\ /g")
~/tmp/directory with spaces$ echo $workingDirectory 
/home/user/tmp/directory\ with\ spaces
~/tmp/directory with spaces$ strace /bin/echo $workingDirectory |& grep '^execve'
execve("/bin/echo", ["/bin/echo", "/home/user/tmp/directory\\", "with\\", "spaces"], [/* 62 vars */]) = 0

因此,一个明显的解决方法是将其设置$IFS为空字符串(并完全避免转义空格),从本质上完全禁用单词拆分:

~/tmp/directory with spaces$ workingDirectory=$(pwd)
~/tmp/directory with spaces$ echo $workingDirectory 
/home/user/tmp/directory with spaces
~/tmp/directory with spaces$ IFS=
~/tmp/directory with spaces$ strace -s 64 /bin/echo $workingDirectory |& grep '^execve'
execve("/bin/echo", ["/bin/echo", "/home/user/tmp/directory with spaces"], [/* 62 vars */]) = 0
~/tmp/directory with spaces$ stat $workingDirectory
  File: ‘/home/user/tmp/directory with spaces’
  Size: 4096        Blocks: 8          IO Block: 4096   directory
Device: 812h/2066d  Inode: 782086      Links: 2
Access: (0775/drwxrwxr-x)  Uid: ( 1000/    user)   Gid: ( 1000/    user)
Access: 2016-03-24 11:22:43.606332994 +0100
Modify: 2016-03-24 10:51:00.835689309 +0100
Change: 2016-03-24 10:51:00.835689309 +0100
 Birth: -

但是,完全禁用分词功能一般来说意义不大。除非您有充分的理由完全禁用多个命令的分词功能,否则我建议您仅使用双引号将其限制在可能包含字段分隔符的字符串中:

workingDirectory=$(pwd)
cp "$workingDirectory"/jad/jad /usr/bin/

相关内容