2010-03-18 63 views
5

我正在写一个脚本来ssh进入机器列表并将一个变量与另一个值进行比较..我遇到了一个问题(我有几个解决方法,但在这一点上我是只是想知道为什么这种方法不起作用)。凌乱的bash变量

VAR=`ssh $i "awk -F: '/^bar/ {print \$2}' /local/foo.txt"` 

($我会是一个主机名的主机是值得信赖的,没有密码提示中给出。)foo.txt的的

例子:

foo:123456:abcdef 
bar:789012:ghijkl 
baz:345678:mnopqr 

我假定这是一个问题用引号,或者在某处需要。我试了几种方法(不同的引用,使用$()而不是``等),但似乎无法做到。我的脚本正在使用以下工作正常:

VAR=`ssh $i "grep bar /local/foo.txt" | awk -F: '{print \$2}'` 

就像我说的,只是一个好奇心,任何反应表示赞赏。

忘了发布我的输出结果:awk正在吐出整个匹配的行,而不是第二部分。用引号和\'有点玩,我似乎得到了关于“{打印”命令找不到等错误,就好像有一个新的行在那里。

+0

你可能会得到更多的ServerFault响应,关系到我的问题有:http://serverfault.com/ques tions/99886/ssh-not-redirecting -stdout-to-local-terminal – 2010-03-18 18:27:36

+0

如果从第一个示例中删除插入符号,会发生什么情况?也许在这条线的开头有一个看不见的角色。 – danben 2010-03-18 18:29:02

+0

@Lance Roberts - 这个问题是关于awk,而不是ssh,因此适用于堆栈溢出。 – danben 2010-03-18 18:29:29

回答

5

sshd命令bash执行,所以它会通过远程端的bash解释器以及执行脚本的端。让我们来看看你的命令:

VAR=`ssh $i "awk -F: '/^bar/ {print \$2}' /local/foo.txt"` 

你已经正确地躲过了$2为本地计算机,使你在执行bash脚本不解释它。但是,所有的报价是由它获取的awk(我不完全知道为什么内部报价遭到移除)的时间去掉,它的执行这样的:在远程端

awk -F: /^bar/ {print $2} /local/foo.txt 

bash中看到$ 2和替换它用空字符串,留给你:

awk -F: /^bar/ {print } /local/foo.txt 

这就是为什么它会打印整行。那么你如何解决它?你可以逃脱在远程端什么bash将用斜杠来执行,就像这样:

VAR1=`ssh $i localhost "echo awk -F: '/^bar/ {print \\\$2}' /local/foo.txt"` 

另外,你可以只回声命令,看看有什么庆典是真正执行为你调试你再进一步的问题跨越:

VAR1=`ssh $i localhost "echo awk -F: '/^bar/ {print \$2}' /local/foo.txt"` 
echo VAR1: $VAR1 

Execute it and see this output and see right away that it has removed $2: 
VAR1: awk -F: /^bar/ {print } /local/foo.txt 
+0

这不是引号被任意删除,而是远程端的shell正在解释它们。编写命令行。引用它的远程外壳。引用它的本地外壳。 – 2010-03-18 20:40:39

+0

Ahhh我很近!谢谢! – Kyle 2010-03-18 20:45:01

+0

@Chris Johnsen:当我通过''...'{print \ $ 2} \'..''试验时,我迷惑了自己。我在远程方面看到它在表达式周围有正确的''',但$ 2'仍然缺失。但在阅读你所说的内容之后,它是有道理的,因为它正在用'''替换'\',同时它会替代'$ 2'。我知道这不是魔术,我无法马上解释它。 ;)谢谢澄清。 – indiv 2010-03-18 21:08:28

0

尝试尽可能使用$()语法

VAR=$(ssh $i "awk -F: '/^bar/ {print \$2}' /local/foo.txt")