读取命令删除双空格并仅保留一个

读取命令删除双空格并仅保留一个

我编写了一个脚本,用于收集本地计算机上的应用程序日志,然后从远程计算机上收集应用程序日志。

它有一个变量oldlogsdate,可以读取我想要收集的日志的日期。

例如,如果我输入Apr 23它工作正常,因为只有一个空格,但如果我输入(和Apr 4之间有两个空格)它将删除一个空格。Apr4

注意:这oldlogsdate也是在用户的远程机器上设置的.bash_profile,然后使用命令更改输入的日期sed

printf "\n";read -p "Which Date Logs you want to collect = " oldlogsdate
ssh -qt [email protected] "sed -i "s/oldlogsdate=.*/oldlogsdate=\'\"$oldlogsdate\"\'/" ~/.bash_profile"

oldlogsdate="Apr 7"

现在我为什么要使用它Apr 23Apr 4它是命令的一部分ls

有没有办法在读取命令中保留双空格,或者其他更好的方法?

在此输入图像描述

答案1

请注意您的命令行,即发送到另一端的命令ssh部分:sed

ssh ... "sed -i "s/oldlogsdate=.*/oldlogsdate=\'\"$oldlogsdate\"\'/" ~/.bash_profile"
        ^^^^^^^^^..................................................^^^^^^^^^^^^^^^^^^

这里有两个带引号的字符串,标有^.中间剩下的就是不是引用,其中包括变量扩展$oldlogsdate。由于它没有被引用,所以它受到分词,并Apr 7变成两个单词Aprand 7。也可以看看:什么时候需要双引号?

现在,ssh它足够聪明,可以将它们重新粘在一起,但现在原始的空白量已经丢失,而只是添加了一个空格。

这有点类似于 shell 如何忘记其中的原始空白量并将echo单词与单个空格粘合在一起:

$ echo hello  world
hello world

但请注意,对于 SSH,单层引号没有帮助,因为 SSH 将命令行传递给远程端的 shell 进行解释,并且在该 shell 中,单词之间的额外空格也会丢失。

所以这仍然不起作用:

$ ssh localhost echo "hello  world"
hello world

(本地 shell 删除引号,ssh获取echohello world,然后传递到远程echo hello world,其工作方式如上。)

实际上我们必须对两端进行引用以保持字符串完整:

$ ssh localhost 'echo "hello  world"'
hello  world

实际上,最好使用printf ":%s\n" hello worldetc.来更正确地显示断词的位置,但结果是相似的。

切换引号以使双引号位于最外层,让本地 shell 扩展变量,并为远程 shell 保留单引号,从而最大程度地减少扩展量。您仍然需要对要发送到另一端的任何双引号进行反斜杠转义。

$ greeting="hello  world"
$ ssh localhost "echo '$greeting'"
hello  world

只要变量本身不包含单引号,就应该可以工作。如果是这样,事情会变得更难看,请参阅:转义变量以用作另一个脚本的内容

我认为命令行@萨莎的回答看起来它应该适合你的情况。

另请参阅,例如这个问题:在 ssh $host $FOO 和 ssh $host "sudo su user -c $FOO" 类型构造中引用 手头的问题有一个更多的处理层,但答案似乎也适用于“更简单”的情况。

答案2

读取命令删除双空格并仅保留一个

事实并非如此。该read命令本身保持内部空白不变(但是,除非您设置IFS为空,否则它将修剪前导和尾随空白;如果您不使用,它还会损坏反斜杠-r)。

read myVar <<<'Apr  4'
echo "$myVar"  # will output: Apr  4

那就是你因为没有双引号变量而丢失了空格:

myVar2='Apr  4'
echo $myVar2  # will mangle spaces, please always use "$myVar2" instead

不正确引用变量不仅会使脚本行为异常,还可能引入潜在的安全风险。

一点点更正确的命令是

ssh -qt [email protected] "sed -i 's/oldlogsdate=.*/oldlogsdate=\"$oldlogsdate\"/' ~/.bash_profile"

但它并不通用,而且也不安全,因为它没有考虑到该$oldlogsdate值不仅可能包含空格,还可能包含撇号、斜杠、反斜杠、美元符号和感叹号。

相关内容