这个问题有点复杂。我会尝试详细解释。
我有两台机器,一台是本地的,另一台是192.168.1.2
.我在本地机器中设置了以下变量
CHECK="/home/test/Desktop/"
test
我的本地计算机和远程计算机中都存在一个名为的用户。我想通过 ssh 从本地运行以下命令。
ssh -n [email protected] "until [ `cat $CHECK/samplefile | grep "string"` ]; do touch $CHECK/success; done"
我想要实现的是,我想检查 $CHECK/samplefile 中是否有远程计算机中名为“string”的条目。一旦找到,我想退出until
循环并进一步进行。但是当我运行此命令时,我收到以下错误消息。
cat: /home/test/Desktop//samplefile: No such file or directory
但我非常确定我的远程计算机在test
用户桌面中包含文件名samplefile。经过进一步的研究,我发现反until
引号中给出的条件语句实际上运行于local
而不是remote
(我的本地桌面中不包含这样的文件)。此外,直到循环中的其余命令工作正常,并且在远程计算机的桌面中创建了一个名为 success 的新文件。
我不确定问题是否出在反引号或直到。过去3个小时我一直被困在这个问题上。有什么建议么?
答案1
正如您在问题中注意到的那样,这种替换:
`cat $CHECK/samplefile | grep "string"`
是在您的本地计算机上执行的。您可以通过以下方式轻松修复它:
ssh -n [email protected] \
"until { cat ""$CHECK""/samplefile | grep ""string""; }; do \
touch ""$CHECK""/success; \
done"
正如您所看到的,除了解析变量之外,您不需要任何替换$CHECK
。您可以将条件指令放入{...}
列表中,现在列表的退出代码对于until
指令来说是决定性的。
答案2
你说得对,这就是引用。通过使用双引号将远程命令括起来,您可以告诉本地 shell 解释它可以传递给 ssh 会话的任何内容。在这种情况下,cat
命令。
如果将命令用单引号引起来,则不会出现该问题,但也无法扩展在单引号之外定义的变量。
本地文件:
bash-[501]$ echo $(hostname) > /tmp/samplefile
bash-[506]$ echo $(cat /tmp/samplefile)
tank
创建远程文件:
bash-[502]$ ssh evil 'echo $(hostname) > /tmp/samplefile'
bash-[501]$ cat /tmp/samplefile
evil
尝试用双引号查看远程文件:
bash-[508]$ ssh evil "echo `cat /tmp/samplefile`"
tank
尝试用单引号查看远程文件:
bash-[509]$ ssh evil 'echo `cat /tmp/samplefile`'
evil
将文件定义为要在远程端处理的变量:
bash-[527]$ ssh evil 'F=/tmp/samplefile; cat $F'
evil
在您的情况下,将命令用单引号括起来,并$CHECK
在这些引号内进行定义,足以发送要在远程端解释的所有内容。
ssh -n [email protected] 'CHECK=/home/test/Desktop; until [ `cat $CHECK/samplefile | grep "string"` ]; do touch $CHECK/success; done'
答案3
export CHECK='/home/test/Desktop'
ssh -n [email protected] 'until [ `cat "$CHECK/samplefile" | grep "string"` ]; do touch "$CHECK/success"; done'