2011-01-23 5 views
58

Я пишу сценарий оболочки, который должен быть несколько безопасным, т. Е. Не передает защищенные данные через параметры команд и предпочтительно не использует временные файлы. Как передать переменную в команду stdin? Или, если это невозможно, как правильно использовать временные файлы для такой задачи?Как передать значение переменной в stdin команды?

+0

Может ли злоумышленник изменить '$ PATH'? Так что 'cat' можно заменить be'/bin/cat '$ @ "| tee/attacker/can/read/this/file' – 12431234123412341234123

ответ

47

Что-то же просто, как:

echo "$blah" | my_cmd 
+6

Остерегайтесь пробелов в вашей переменной: 'echo '$ blah" 'лучше. –

+0

@ Джонатан: Это хороший момент. Ответ обновлен соответствующим образом ... –

+3

Будет ли это работать, даже когда есть '' 'в' $ blah'? –

5

Попробуйте это:

echo "$variable" | command 
+0

, но не будет отображаться переменная $ content, например. вывод 'ps -u', когда работает эхо? –

+2

нет. 'echo' является встроенным, поэтому в ps нет никакого процесса. – unbeli

+1

Остерегайтесь пробелов в вашей переменной:' echo '$ variable "' лучше. –

11
(cat <<END 
$passwd 
END 
) | command 

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

+0

Но этот метод позволяет передавать несколько строк в вашу команду, а также позволяет пробелы в '$ passwd' – PoltoS

+0

. Это лучший ответ до сих пор, который не пропускает переменное содержимое для отслеживания труб или процессов. – user2688272

117

Передача значения на стандартный ввод так же просто, как:

your-command <<< "$your_variable" 

Всегда убедитесь, что вы положили в кавычки переменных выражений!

+30

Herestrings '<<<' не являются gua насколько я знаю, они не находятся в базе POSIX. Они будут работать, как ожидалось, до тех пор, пока вы используете их только в «bash». Я только упоминаю об этом, потому что они ОП заявили «оболочка», а не «баш». Хотя он и поставил вопрос «bash» ... так что это, очевидно, приемлемый ответ. – TechZilla

+0

Хотя это может быть так, чувствительная информация, скорее всего, будет легче утечка при использовании метода 'echo' из-за создания трубы. Команда herestring будет полностью обработана 'bash', хотя в этой ситуации (как указано) вам лучше знать, что она будет работать на вашем bash, иначе любое сообщение об ошибке, появившееся в результате отсутствия поддержки herestrings, также будет утечка указанной информации , –

+0

@StevenLu Подождите, 'echo' является встроенным. Там нет трубы, верно? Это Unix, но это не может быть так много Unix *. –

15

Обратите внимание, что операции 'echo "$var" | command означают, что стандартный ввод ограничен эхо-сигналом. Если вы хотите, терминал должны быть подключены, то вам нужно быть любителем:

{ echo "$var"; cat - ; } | command 

(echo "$var"; cat - ) | command 

Это означает, что первая линия (s) будет содержанием $var, но остальное будет исходить от cat считывая стандартный ввод. Если команда не делает ничего необычного (попробуйте включить редактирование командной строки или запустите как vim), тогда все будет хорошо. В противном случае вам нужно получить действительно фантазию - я думаю, что expect или одна из ее производных, вероятно, будет уместной.

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

+0

'(echo" $ LIST "; cat -) | sed 1q это работает для меня, но мне нужно нажать ctrl d, когда я запустил этот скрипт? –

+0

Да,' cat'' продолжает читать с клавиатуры до EOF или прерывания, поэтому вам нужно сказать EOF, набрав control-D. –

+0

есть ли способ вокруг EOF? sed нужен cat –

5

Согласно ответу Мартина, есть Баш функция называется Здесь Струны (который сам по себе является разновидностью более широко поддерживаются Здесь документов признака).

http://www.gnu.org/software/bash/manual/bashref.html#Here-Strings

3.6.7 Здесь Струны

Вариантом здесь документы, формат:

<<< word 

Слово расширяется и подается команда на его стандартный вход.

Обратите внимание, что здесь будут появляться строки, чтобы быть Баш-только, так, для улучшения переносимости, вы, вероятно, будет лучше с оригиналом Здесь документы представлены, в соответствии с ответом PoltoS'S:

(cat <<EOF 
$variable 
EOF 
) | cmd 

Или, более простой вариант вышеизложенного:

(cmd <<EOF 
$variable 
EOF 
) 

вы можете опустить ( и ), если вы не хотите, чтобы это перенаправлены дальше в другие команды.

11

Мне понравился ответ Мартина, но он имеет некоторые проблемы в зависимости от того, что находится в переменной. ! Это

your-command <<< """$your_variable""" 

лучше, если переменная содержит "или

+2

Но почему? Кроме того, я не могу воспроизвести никаких проблем: 'foo1 = -; foo2 = '"'; foo3 = \ !; cat <<<" $ foo1 "; cat <<<" $ foo2 "; cat <<<" $ foo3 "' отлично работает для меня. Что именно делают три ' 'делать? AFAIK вы просто добавляете и добавляете пустую строку. – phk

+0

Попробуйте что-то реальное. Как и ваша команда ssh somehost. и ваша переменная - это сценарий оболочки. –

0

Вобще:

printf "$my_var" | my_cmd 

Если переменная не содержит пробелы, кавычки могут быть опущены
При использовании. bash, то вы также можете сделать:

echo -n "$my_var" | my_cmd 

Избегайте использования usi ng echo без -n, потому что в конце он будет транслировать рендеринг с добавленной последовательностью строк.

Смежные вопросы