Bash脚本:保持本地文件的一行与远程文件同步



我到处找,但似乎找不到这个问题的解决方案(也许它不存在?)。这是我的问题:

我在本地机器上有一个名为myFile.txt的文件。在远程机器上有个同名文件(myFile.txt)。两个文件结构如下:

<tag1>November 22, 2012<tag1>
<tag2>version5.8<tag2>
<tag3>ASDFA23RASDF29ASDJ29DJ2<tag3>

两个文件的布局完全相同。我需要编写一个脚本,使<tag3>之间的字符串与两个文件(本地和远程)保持同步。我需要从远程服务器上的<tag3>获取字符串,并将其与本地计算机上的相同字符串进行比较。如果有差异,我需要更改本地字符串以反映远程字符串。

到目前为止,我已经尝试过:我已经使用awk获取了本地字符串,并将其分配给一个变量。很简单。我进入远程服务器,尝试使用相同的方法将远程字符串分配给变量。据我所知,这似乎奏效了。问题是变量没有带值返回到我的本地机器(如果有意义的话)。这就是我试图做到的:

#!/bin/bash
fileName="myFile.txt"
logon="myUserName@remoteServer.com"

localString=$(awk -F "<tag3>" '{print $2}' $fileName)
x=$(ssh $logon "remoteString=$(awk -F "<tag3>" '{print $2}' $fileName); echo $remoteString")
echo "remote string = $x" 
if [ $localString == $x ]; then
echo "The 2 auth keys are EQUAL!!!"
else
echo "The 2 auth keys are NOT equal!!!"
fi  

当我回显$remoteString时,我可以看到正在分配的变量。据我所知,这是在远程服务器上发生的,因为我正在将正确的字符串打印到控制台,然后是"找不到命令"。下一行回显的"remote string="。所以$x要么正在失去它的价值,要么从未被正确分配。我多次尝试更改$x的赋值行,但都没有成功。

其他想法:如果这不可能,我开始想,也许我需要对文件进行scp,把它带到我的服务器上,进行比较,然后删除复制的文件。在将副本移动到本地计算机之前,我需要更改副本的名称,否则我将覆盖我的文件。此外,不必制作安全副本似乎更有效,因为该脚本必须在许多机器上运行,并且文件可能比3行大得多。我研究过diff,但找不到只比较一行的方法。

我对bash脚本还很陌生,所以如果我遗漏了一些明显的内容,请原谅我。非常感谢您的帮助。

您可以使用以下内容:

#!/bin/bash 
fileName="myFile.txt"
logon="myUserName@remoteServer.com"
sedcommand='/^<tag3>.*<tag3>$/{s/<tag3>(.*)<tag3>/1/p;q}'
localString=$( sed -n $sedcommand "$fileName" )
remoteString=$( ssh "$logon" "sed -n '$sedcommand' "$fileName"" )
if [[ $localString == $remoteString ]]; then
echo "The 2 auth keys are EQUAL!!!"
else
echo "The 2 auth keys are NOT equal!!!"
fi

(这似乎比你的方法更简单)。sed命令查找以<tag3>开始、以<tag3>结束的第一行,并删除标记,以便仅传输"auth-key"。对于不存在的文件或找不到标签,没有任何防范措施。这个细节留给读者。但是该脚本对于文件名中的空格是安全的,并且不使用两个嵌套的子shell!

ssh命令存在转义问题-应该在ssh参数中转义$

然后,我只是用awk ....替换了remoteString=$(awk ....); echo $remoteString。如果不是,那么前面的空白行会导致字符串不匹配,并且只将命令的输出存储到echo似乎是没有用的。

#!/bin/bash
fileName="myFile.txt"
logon="myUserName@remoteServer.com"

localString=$(awk -F "<tag3>" '{print $2}' $fileName)
x=$(ssh $logon "awk -F '<tag3>' '{print $2}' $fileName")
echo "remote string = $x" 
if [ "$localString" == "$x" ]; then
echo "The 2 auth keys are EQUAL!!!"
else
echo "The 2 auth keys are NOT equal!!!"
fi

尝试更改此行:

x=$(ssh $logon "remoteString=$(awk -F "<tag3>" '{print $2}' $fileName); echo $remoteString")

x=$(ssh $logon "remoteString=$(awk -F '<tag3>' '{print $2}' $fileName); echo $remoteString")

即:将"<tag3>"更改为'<tag3>'

我有一种感觉,您当前使用双引号实际上破坏了ssh命令的预期用途。


附带说明:当您为条件测试选择[时,请始终将变量用双引号括起来:

if [ $localString == $x ]; then

会更安全,因为:

if [ "$localString" == "$x" ]; then

# this also works, but less portable
if [[ $localString == $x ]]; then

原因是,如果任何一个变量的计算结果为空字符串(假设在这种情况下x为空),bash将看到类似的内容:if [ ASDFA23RASDF29ASDJ29DJ2 == ]; then

相关内容

  • 没有找到相关文章

最新更新