Bash:Insert转义到包含空格的变量

Bash:Insert转义到包含空格的变量,bash,escaping,spaces,Bash,Escaping,Spaces,正在尝试使用bash中的scp将远程文件复制到本地系统 我已获得所需的文件名并分配给变量,$lastModifiedFile, 但问题是文件名中包含空格。 要将此变量与scp一起使用,需要使用反斜杠转义空格。 是否有一种简单的方法可以格式化此变量并在必要时插入正确的转义字符,即空格? #!/bin/bash lastModifiedFile=$(sshpass -p 'passw0rd' ssh user@server 'ls -tr /path/output*| tail -n 1') ec

正在尝试使用bash中的scp将远程文件复制到本地系统
我已获得所需的文件名并分配给变量,
$lastModifiedFile

但问题是文件名中包含空格。
要将此变量与scp一起使用,需要使用反斜杠转义空格。
是否有一种简单的方法可以格式化此变量并在必要时插入正确的转义字符,即空格?

#!/bin/bash

lastModifiedFile=$(sshpass -p 'passw0rd' ssh user@server 'ls -tr /path/output*| tail -n 1')
echo "$lastModifiedFile"

sshpass -p 'passw0rd' scp user@server:"$lastModifiedFile" /root/
这是脚本输出

[user@host ~]# ./script.sh 
/path/outputSat Mar 09 151905 GMT 2013.html
scp: /path/outputSat: No such file or directory
scp: Mar: No such file or directory
scp: 09: No such file or directory
scp: 151905: No such file or directory
scp: GMT: No such file or directory
scp: 2013.html: No such file or directory
我在寻找下面这样的东西,或者更简单的解决方案

escapedFilename=""

for letter in $lastModifiedFile
    if $letter == " "
        $escapedFilename += "\ "
    else
        $escapedFilename += $letter
就这样做吧:

sshpass -p 'passw0rd' scp 'user@server:$lastModifiedFile' /root/

有点倾斜牙签综合症:

param=user@server:${lastModifiedFile//\\/}

sshpass-p'passw0rd'scp“$param”/root/

编辑:似乎
scp
不喜欢我。我需要在测试中增加一个变量级别…:)

编辑2:根据OP的反馈,确切的解决方案似乎包括使用
${lastModifiedFile//\\}

我只希望在其他一些文件名中,除了空格之外,没有其他字符需要转义:)

这里有几个方法可以处理文件名中的几乎任何内容(不仅仅是空格)。首先,bash的
printf
内置了一种
%q
格式,可以在字符串中添加引号/转义符/任何内容:

sshpass -p 'passw0rd' scp user@server:"$(printf %q "$lastModifiedFile")" /root/
但是,请注意,这引用/转义/etc适合于bash的解释。如果远程计算机的默认shell是其他的,那么这可能不会在所有情况下都起作用

选项二在原则上更简单(但在实践中有点混乱),并且应该与更多的远程shell兼容。在这里,我用单引号将文件名括起来,这应该适用于文件名中除单引号以外的任何内容。对于这些,我将替换为
'\'
(它结束单引号字符串,添加转义单引号,然后重新启动单引号字符串):


在传递给远程系统的文件名周围使用单引号,这样它就不会被分词

lastModifiedFile=$(sshpass -p 'passw0rd' ssh user@server 'ls -tr /path/output*| tail -n 1')
echo "$lastModifiedFile"

sshpass -p 'passw0rd' scp user@server:"'$lastModifiedFile'" /root/


牙签的输出似乎不正确
scp:/path/outputSat/Mar/09/151905/GMT/2013.html:没有这样的文件或目录
。。这些应该是放在空格前的反斜杠<代码>A=“/tmp/foo-bar-baz”;B=10.0.1.119:${A//\\};scp“$B”/test为我工作。可能取决于使用的shell?使用Bash。。这就是最终的效果,
${lastModifiedFile//\\\}
。。谢谢你的帮助!想更新你的答案,我会接受的?这对我不起作用。即使在控制台中键入我需要的
'server:foo\bar'
,也不需要
server:foo\bar
'server:foo bar'
就足够了。这给了我
scp/path/outputSun 2013年3月3日格林威治标准时间072433 GMT.html
,它没有转义,甚至无法手动工作
lastModifiedFile=$(sshpass -p 'passw0rd' ssh user@server 'ls -tr /path/output*| tail -n 1')
echo "$lastModifiedFile"

sshpass -p 'passw0rd' scp user@server:"'$lastModifiedFile'" /root/
sshpass -p 'passw0rd' scp "user@server:'$lastModifiedFile'" /root/