我搜索过高和低,但似乎无法找到解决这个问题的方法(也许它不存在?)。这是我的问题:
我的本地计算机上有一个名为myFile.txt的文件。远程计算机上有一个名称相同的文件(myFile.txt)。两个文件结构都是这样的:
<tag1>November 22, 2012<tag1>
<tag2>version5.8<tag2>
<tag3>ASDFA23RASDF29ASDJ29DJ2<tag3>
两个文件都具有完全相同的布局。我需要编写一个脚本,使两个文件(本地和远程)的<tag3>
之间的字符串保持同步。我需要从远程服务器上的<tag3>
获取字符串,并将其与本地计算机上的相同字符串进行比较。如果存在差异,我需要更改本地字符串以反映远程字符串。
到目前为止我尝试过的事情: 我使用awk抓取了本地字符串,并将其分配给变量。很容易。我ssh'ed到远程服务器并尝试使用相同的方法将远程字符串分配给变量。据我所知,这似乎有效。问题是变量没有返回我的本地机器有一个值(如果这是有道理的)。这就是我试图这样做的方式:
#!/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时,我可以看到分配的变量。根据我的理解,这是在远程服务器上发生的,因为我正在将正确的字符串打印到控制台,然后是“未找到命令”。下一行echo是“remote string =”。所以$ x要么丢失它的值,要么从未正确分配。我已经尝试改变这一行,其中$ x被分配很多次,但没有任何运气。
其他想法: 如果这是不可能的,我开始认为我可能需要做一个文件的scp,把它带到我的服务器,进行比较,然后删除复制的文件。我需要在将副本移动到本地计算机之前更改副本的名称,否则我将覆盖我的文件。此外,不必制作安全副本似乎更有效,因为此脚本必须在许多计算机上运行,并且该文件可能比3行大很多。我已经研究了差异,但是找不到让它比较一条线的方法。
我对bash脚本很新,所以如果我遗漏了一些明显的东西,请原谅我。感谢您的帮助,非常感谢。
答案 0 :(得分:1)
ssh
命令存在一个转义问题 - 您应该转义$
参数中的ssh
。
然后,我只用remoteString=$(awk ....); echo $remoteString
替换了awk ....
。如果没有,则存在一些导致空白行不匹配的问题 - 将命令的输出仅存储到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
答案 1 :(得分:1)
您可以使用以下内容:
#!/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!
答案 2 :(得分:0)
尝试更改此行:
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