混乱的 bash 变量

发布于 2024-08-25 15:39:50 字数 619 浏览 4 评论 0原文

我正在编写一个脚本来 ssh 到机器列表并将变量与另一个值进行比较。我遇到了一个问题(我有几个解决方法,但此时我只是想知道为什么这个方法不不工作)。

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

($i 将是一个主机名。主机是受信任的,不会给出密码提示)

foo.txt 的示例:

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

我假设这是引号的问题,或者在某处需要 \。我已经尝试了几种方法(不同的引用,使用 $() 而不是 `` 等),但似乎无法得到正确的结果。我的脚本使用以下内容可以正常工作:

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

就像我说的,只是出于好奇,任何回应都会受到赞赏。

忘记发布我的输出是什么:awk 吐出整个匹配行,而不是第二部分。使用引号和 \'s a bit 我似乎收到了有关“{print”命令未找到等的错误,就好像某处有一个新行一样。

I'm writing a script to ssh in to a list of machines and compare a variable to another value.. I've run into a problem (I have a couple workarounds, but at this point I'm just wondering why this method isn't working).

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

($i would be a hostname. The hosts are trusted, no password prompt is given)

Example of foo.txt:

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

I'm assuming it's a problem with quotes, or \'s needed somewhere. I've tried several methods (different quoting, using $() instead of ``, etc) but can't seem to get it right. My script is working correctly using the following:

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

Like I said, just a curiousity, any response is appreciated.

Forgot to post what my output was: awk is spitting out the whole matched line, not the 2nd section. Playing with the quotes and \'s a bit I seemed to get an error about "{print " command not found etc, as if there was a new line in there somewhere.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

半边脸i 2024-09-01 15:39:50

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"`

另外,您可以仅回显该命令以查看 bash 真正执行的内容,以便调试您遇到的任何进一步问题:

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

sshd gives your command to bash to execute, so it'll go through the bash interpreter on the remote side as well as the side you're executing the script on. Let's look at your command:

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

You've properly escaped the $2 for your local machine so that the bash script you're executing does not interpret it. But all the quotes are being removed by the time it gets to awk (I'm not entirely sure why the internal quotes get removed) and it's executing this:

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

bash on the remote side sees $2 and replaces it with an empty string, leaving you with this:

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

That's why it prints the entire line. So how do you fix it? You can escape what bash on the remote side will be executing with a slash, like so:

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

Also, you can just echo the command to see what bash is really executing for you to debug any further problems you come across:

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
初见终念 2024-09-01 15:39:50

尽量使用 $() 语法

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

try to use the $() syntax as far as possible

VAR=$(ssh $i "awk -F: '/^bar/ {print \$2}' /local/foo.txt")
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文