Я пишу сценарий оболочки, который должен быть в некоторой степени безопасным, т.е. не передавать защищенные данные через параметры команд и, желательно, не использовать временные файлы. Как передать переменную в стандартный ввод команды? Или, если это невозможно, как правильно использовать временные файлы для такой задачи?
105
$PATH
? Так чтоcat
можно заменить/bin/cat "$@" | tee /attacker/can/read/this/file
Ответы:
Что-то простое:
источник
echo "$blah"
лучше.blah=-n
,blah=-e
... используйтеprintf
вместо этого. unix.stackexchange.com/questions/65803/…printf '%s\n' "$blah"
? С этим изменением (избегая многих ошибок вecho
«s спецификации, который отличный ответ Стефан идет в подробно на Почемуprintf
лучшеecho
? На Unix и Linux , или которые раздел ПРИМЕНЕНИЮ изecho
спецификации прикосновений более кратко) это прекрасно разумный ответ.Передать значение
stdin
в bash так же просто:Обязательно заключайте в кавычки выражения переменных!
источник
<<<
не гарантируется, насколько мне известно, их нет в базе POSIX. Они будут работать, как ожидалось, пока вы их только запускаетеbash
. Я упоминаю об этом только потому, что OP сказал «оболочка», а не «bash». Хотя он пометил вопросbash
... так что это, очевидно, приемлемый ответ.echo
метода утечка конфиденциальной информации может быть проще из-за создания канала. Команда herestring будет полностью обработанаbash
, хотя в этой ситуации (как уже отмечалось) вам лучше знать, что она будет работать на вашем bash, иначе любое сообщение об ошибке, созданное в результате отказа от поддержки herestrings, также приведет к утечке указанной информации.echo
это встроенный. Там нет трубы, да? Это Unix, но не может быть так много Unix .printf '%s\n' "$var"
дает те же результаты, что и,echo "$var"
но не сломается, напримерvar=-en
, и даже не требует bash.Обратите внимание, что
echo "$var" | command
операции ' означают, что стандартный ввод ограничен отображаемой строкой (ами). Если вы также хотите, чтобы терминал был подключен, вам нужно быть более изящным:Это означает, что первая строка (строки) будет содержимым,
$var
а остальная часть будет получена приcat
чтении стандартного ввода. Если команда не делает ничего особенного (попробуйте включить редактирование командной строки или выполните аналогичные действияvim
), тогда все будет в порядке. В противном случае вам нужно по-настоящему фантазировать - я думаю,expect
или одна из его производных, вероятно, будет подходящей.Обозначения командной строки практически идентичны, но вторая точка с запятой необходима с фигурными скобками, тогда как круглые скобки не используются.
источник
( echo "$LIST"; cat - ) | sed 1q
это работает для меня, но мне нужно нажать ctrl d, когда я запускаю этот скрипт?cat -
продолжает читать с клавиатуры до EOF или прерываний, так что вы должны сказать ему EOF, набрав управление-D.cat
если вам не нужен ввод терминала, как в первой строке. Или вы можете использоватьcat
для вывода списка файлов. Или ... Если вы хотите, чтобы команда считывала ввод терминала, вы должны сообщить ей, когда она достигла конца ввода. Или вы можете использовать( echo "$var"; sed /quit/q - ) | command
; это продолжается до тех пор, пока вы не наберете строку, содержащую «выйти». Вы можете бесконечно изобретать, как с этим справиться. Остерегайтесь старой городской легенды о программе, которая перестала работать, когда пользователи начали работать с Эквадором. Они набирали название столицы, Кито, и программа закрывалась.echo "$LIST" | sed 1q | ...
? Все зависит от того, чем вы занимаетесь.<<EOF
Обозначения должны требовать EOF в начале линии на своей собственной где - то файл. Думаю, я бы не стал его использовать, но я все еще не уверен, чего вы пытаетесь достичь. Простойecho "$LIST" | command
илиecho $LIST | command
, вероятно, будет достаточным на практике (и важно, чтобы вы знали значение разницы между ними).Мне понравился ответ Мартина, но у него есть некоторые проблемы в зависимости от того, что находится в переменной. это
лучше, если ваша переменная содержит "или!"
источник
foo1=-; foo2='"'; foo3=\!; cat<<<"$foo1"; cat<<<"$foo2"; cat<<<"$foo3"
у меня работает нормально. Что именно делают трое"
? AFAIK вы просто добавляете и добавляете пустую строку.На
cat
самом деле не нужен, но он помогает лучше структурировать код и позволяет вам использовать больше команд в круглых скобках в качестве входных данных для вашей команды.источник
$passwd
Согласно ответу Мартина, есть функция bash под названием Here Strings (которая сама по себе является вариантом более широко поддерживаемой функции Here Documents ).
http://www.gnu.org/software/bash/manual/bashref.html#Here-Strings
Обратите внимание, что Here Strings, похоже, предназначены только для bash, поэтому для улучшения переносимости вам, вероятно, будет лучше использовать исходную функцию Here Documents, согласно ответу PoltoS:
Или более простой вариант вышеперечисленного:
Вы можете опустить
(
и)
, если не хотите, чтобы это перенаправлялось дальше в другие команды.источник
Этот надежный и портативный способ уже появлялся в комментариях. Это должен быть отдельный ответ.
или
Ноты:
echo
, причины здесь: Почемуprintf
лучше чемecho
?printf "$var"
неправильно. Первый аргумент формата , где различные последовательности нравится%s
или\n
которые интерпретируются . Чтобы передать переменную правильно, ее нельзя интерпретировать как формат.Обычно переменные не содержат завершающих символов новой строки. Первая команда (с
%s
) передает переменную как есть. Однако инструменты, работающие с текстом, могут игнорировать или жаловаться на неполную строку (см. Почему текстовые файлы должны оканчиваться новой строкой ? ). Таким образом, вам может понадобиться последняя команда (с%s\n
), которая добавляет символ новой строки к содержимому переменной. Неочевидные факты:<<<"$var" my_cmd
) добавляет новую строку .my_cmd
, даже если переменная пуста или не определена.источник
Попробуй это:
источник
ps -u
когда выполняется эхо?echo
является встроенным, поэтому в ps нет процесса для отображенияecho "$variable"
лучше.Просто сделать:
Если в переменной var нет пробелов, кавычки можно опустить.
Если вы используете bash, вы также можете:
Избегайте использования echo без -n, потому что он будет передавать vraiable с добавленным переносом строки в конце.
источник
%s
, printf ничего не печатает.my_var="%s"; printf "$my_var";
- может попробоватьprintf "%s" "$my_var" | my_cmd
?