3

我搜索了高低,但似乎找不到解决这个问题的方法(也许它不存在?)。这是我的问题:

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

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

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

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

#!/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 被分配了很多次,但没有任何运气。

Other ideas: If this isn't possible I'm beginning to think maybe I need to do a scp of the file, bring it over to my server, make the comparison, and then delete the copied filed. I would need to change the name of the copy before moving it to my local machine, or else I will overwrite my file. Also, it would seem more efficient not to have to make a secure copy because this script will have to run on many machines, and the file will potentially be a lot bigger than 3 lines. I've looked into diff, but can't find a way to get it to compare just one line.

I am fairly new to bash scripting so please forgive me if I am missing something obvious. Thank you for any help as it is greatly appreciated.

4

3 回答 3

1

There's a escaping issue with the ssh commands - you should escape the $ inside the ssh parameters.

Then, I just replaced the remoteString=$(awk ....); echo $remoteString with just awk ..... If not, there was some issue with a leading blank line that made the strings to not match - and it seems pretty useless to store a command's output just to echoing it.

#!/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
于 2012-11-22T18:11:19.280 回答
1

You can use something along these lines:

#!/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

(which seems simpler than your method). The sed command finds the first occurence of a line starting by <tag3> and ending by <tag3> and removes the tags so as to transfer only the "auth key". There's no guard against files that don't exist, or against the tag not being find. This detail is left to the reader. But the script is safe regarding spaces in file names and doesn't use two nested subshells!

于 2012-11-22T18:58:38.330 回答
0

Try changing this line:

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

to

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

i.e.: change "<tag3>" to '<tag3>'

I have a feeling that your current use of the double quotes is actually breaking the intended use of your ssh command.


As a side note: always wrap your variables in double quotes when you single ['s for condition tests:

if [ $localString == $x ]; then

would be safer as:

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

or

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

The reason is that if either variable evaluates to the null string (suppose in this case x is empty), bash would see something like this instead: if [ ASDFA23RASDF29ASDJ29DJ2 == ]; then

于 2012-11-22T17:34:58.533 回答