Здесь документ в качестве аргумента для функции bash

Можно ли передать здесь документ в качестве аргумента функции bash, а в функции сохранить параметр как многострочную переменную?

Что-то вроде следующих строк:

function printArgs {
echo arg1="$1"
echo -n arg2=
cat <<EOF
$2
EOF
}

printArgs 17 <<EOF
18
19
EOF

или, может быть:

printArgs 17 $(cat <<EOF
18
19
EOF)

У меня есть здесь документ, который я хочу передать в ssh в качестве команд для выполнения, а сеанс ssh вызывается из функции bash.


person Niebelung    schedule 12.01.2011    source источник


Ответы (5)


Если вы не используете что-то, что будет поглощать стандартный ввод, вам придется предоставить что-то, что это делает:

$ foo () { while read -r line; do var+=$line; done; }
$ foo <<EOF
a
b
c
EOF
person Dennis Williamson    schedule 12.01.2011
comment
Просто к сведению. Вы также можете сделать cat /dev/stdin в функции вместо итерации с помощью while - person joebeeson; 11.06.2015
comment
Хотя в принципе это правильно, он будет потреблять новые строки, которые необходимо добавлять для каждого нового $line. Кроме того, переменная должна быть инициализирована как local. - person Marcus; 21.08.2017

Путь к этому был бы возможен:

printArgs 17 "$(cat <<EOF
18
19
EOF
)"

Но почему вы хотите использовать для этого heredoc? heredoc рассматривается как файл в аргументах, поэтому вам нужно (ab) использовать cat, чтобы получить содержимое файла, почему бы просто не сделать что-то вроде:

print Args 17 "18
19"

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

person Robokop    schedule 12.01.2011
comment
Может быть, между EOF и (" должна быть новая строка? - person Vi.; 14.09.2016
comment
Я хочу передать Emacs большую уродливую форму для оценки в пакетном режиме; это идеальный вариант использования этого хака. - person Radon Rosborough; 18.08.2017
comment
И несколько месяцев спустя мне нужно передать большую уродливую форму для оценки GIMP в его пакетном процессоре TinyScheme. Просто кажется, что это продолжается ‹3 - person Radon Rosborough; 05.01.2018
comment
Также обратите внимание, что вы можете подавить раскрытие переменных в heredocs, используя <<"EOF" вместо <<EOF. - person Radon Rosborough; 15.03.2018
comment
Чтобы ответить, почему это полезно: HEREDOCs позволяют мне использовать оба и ' в моих строках, не выходя из кавычки. - person Michael Mol; 13.09.2018

Основываясь на ответе Неда, мое решение позволяет функции принимать входные данные в виде списка аргументов или в виде heredoc.

printArgs() (
  [[ $# -gt 0 ]] && exec <<< $*
  ssh -T remotehost
)

Так что вы можете сделать это

printArgs uname

или это

printArgs << EOF
uname
uptime
EOF

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

person starfry    schedule 26.09.2014
comment
Милый. Очень очень милый. - person Charles Duffy; 15.12.2015

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

$ xargs -0 <<EOF printArgs 17
18
19
EOF

Но для вашего особого случая я предлагаю вам отправить команду на стандартный ввод ssh:

$ ssh host <<EOF
ls
EOF
person Jérôme Pouiller    schedule 11.09.2013
comment
xargs не может вызывать функцию оболочки, так как использует execve(). Таким образом, ограничение функции bash в вопросе уместно - тестирование с помощью обычных команд не годится. - person Charles Duffy; 15.12.2015
comment
@CharlesDuffy Хороший улов - person Jérôme Pouiller; 15.12.2015

Один из способов передать команды ssh через документ и функцию здесь:

#!/bin/sh
# define the function
printArgs() {
echo "$1"
ssh -T remotehost
}
# call it with a here document supplying its standard input
printArgs 17 <<EOF
uname
uptime
EOF

Результаты, достижения:

17
Linux remotehost 2.6.32-5-686 ...
Last login: ...
No mail.
Linux
 16:46:50 up 4 days, 17:31,  0 users,  load average: 0.06, 0.04, 0.01
person Ned Deily    schedule 12.01.2011