Bash:将转义插入包含空格的变量

时间:2013-03-09 17:01:23

标签: bash escaping spaces

尝试使用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

4 个答案:

答案 0 :(得分:1)

有点牙签综合症:

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

sshpass -p 'passw0rd' scp "$param" /root/

编辑:似乎scp不喜欢我。我在测试中需要一个额外的变量......:)

编辑2:根据OP的反馈,完全解决方案似乎包括使用${lastModifiedFile// /\\ \\} 我只是希望除了空间之外没有其他字符需要在其他文件名中转义:)

答案 1 :(得分:1)

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

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/

答案 2 :(得分:0)

就这样做:

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

答案 3 :(得分:0)

以下是一些应该处理文件名中几乎所有内容(不仅仅是空格)的方法。首先,bash的printf内置函数具有%q格式,可以在字符串中添加引号/转义/其他内容:

sshpass -p 'passw0rd' scp user@server:"$(printf %q "$lastModifiedFile")" /root/

但请注意,这引用/ escapes / etc 适合bash 的解释。如果远程计算机的默认shell是其他内容,则可能在所有情况下都不起作用。

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

repl="'\''" # Have to store this in a variable to work around a bash parsing oddity
sshpass -p 'passw0rd' scp user@server:"'${lastModifiedFile//\'/$repl}'" /root/