我到处找,但似乎找不到这个问题的解决方案(也许它不存在?)。这是我的问题:
我在本地机器上有一个名为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