Грязная переменная - PullRequest
       8

Грязная переменная

5 голосов
/ 18 марта 2010

Я пишу скрипт для 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 выплевывает всю совпавшую строку, а не 2-й раздел. Играя с кавычками и немного, я, кажется, получил сообщение об ошибке "{print" команда не найдена и т. Д., Как будто где-то там была новая строка.

Ответы [ 2 ]

5 голосов
/ 18 марта 2010

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
0 голосов
/ 19 марта 2010

попытайтесь использовать синтаксис $(), насколько это возможно

VAR=$(ssh $i "awk -F: '/^bar/ {print \$2}' /local/foo.txt")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...