Неожиданный результат при использовании оператора pipe внутри переменной оболочки

334
hebbo

У меня есть процесс, который выводит некоторые сжатые данные на стандартный вывод. Что я делаю с этим выводом, так это pipe и отправляю его через туннель SSH на другую машину, где он записывается в файл.

Вот так:

/usr/bin/myapp | ssh root@remotemachine "cat > /path/to/output/file.gz" 

когда я sshк машине и вызываю эту строку, все идет хорошо. Но когда я помещаю эту команду в сценарий оболочки, как

#!/bin/sh APP=/usr/bin/myapp OPTS=--gzip OUTPUT= "| ssh root@remotemachine \"cat > /path/to/output/file.gz\"" $APP $OPTS $OUTPUT 

И затем вызвать сценарий, я вижу мусор на консоли, который я могу только предположить, что это вывод myapp, а затем это

Unknown parameter '|' Unknown parameter 'ssh' Unknown parameter 'root@remotemachine' Unknown parameter '"cat' Unknown parameter '>' Unknown parameter '/path/to/output/file.gz"' 

Я предполагаю, что оболочка отправила $OUTPUTраздел в качестве аргумента myappвместо того, чтобы действовать на них. Итак, эти «Неизвестный параметр» пришли myappне из оболочки.

Как я могу это исправить?

0
Вы пробовали / bin / bash вместо / bin / sh? Sirex 5 лет назад 0
Нет, в системе, над которой я работаю, нет bash. Мне нужно ограничить работу пеплом hebbo 5 лет назад 0
Тогда вы не должны использовать `bash` в качестве тега. AFH 5 лет назад 0
хорошо ... убрал это. Но мне было интересно, если моя проблема не связана с пеплом и может на самом деле может произойти в Баш. Итак, я хотел охватить более широкую аудиторию. Кроме того, на данный момент я не там, где проблема. hebbo 5 лет назад 0

2 ответа на вопрос

0
hebbo

Хорошо .... Я нашел то, что мне было нужно. Это была evalкоманда. Это на самом деле ответили здесь .

Итак, скрипт можно изменить следующим образом:

#!/bin/sh APP=/usr/bin/myapp OPTS=--gzip OUTPUT= "| ssh root@remotemachine \"cat > /path/to/output/file.gz\"" eval "$APP $OPTS $OUTPUT" 
0
Kamil Maciorowski

Ваша оболочка анализирует любую командную строку в определенной последовательности. Когда он сталкивается, $APP $OPTS $OUTPUTон видит, что нет оператора трубы; позже эти переменные раскрываются и |появляются, но не имеют особого значения, потому что для этого уже слишком поздно.

Результат может быть переоценен с помощью eval(ваш ответ показывает, что вы уже обнаружили это), но evalможет оказаться ошибкойevil .

Ваш оригинальный подход имеет недостатки, поскольку переменные оболочки не должны содержать код. Функции для кода. Пример:

app=/usr/bin/myapp opts=--gzip output() { ssh root@remotemachine "cat > /path/to/output/file.gz"; } $app $opts | output 

Обратите внимание, что рекомендуется использовать имена переменных в нижнем регистре .

Я не эксперт по написанию сценариев оболочки. Я опробую ваш ответ. Это выглядит лучше, чем у меня. hebbo 5 лет назад 0

Похожие вопросы