26

Связанный с вопросом, который я задал относительно переполнения стека: передача нескольких строк кода в wsadmin.sh? ,

В качестве строки у меня есть несколько строк ввода, которые мне нужно ввести в команду. Команда, однако, принимает только файл, полный ввода.

Можно ли каким-то образом сохранить строки во временном файле или канале, который никогда не будет записан на диск, а затем передать их непосредственно в программу?

Как мне получить трубку, подать в нее входные данные, передать эту команду команде, а затем избавиться от канала?

4 ответа4

23

Другое решение заключается в использовании процесса замены в Bash. Если ваша система имеет именованные каналы, вы можете использовать эту функцию.

Используется так:

program_expecting_a_file <(list)

где list - это последовательность команд оболочки (на самом деле конвейеры; подробности здесь). list будет выполнен, а его выход будет подключен к каналу. Имя канала затем передается в вашу программу.

ПРИМЕЧАНИЕ: пробелы не допускаются между < и ( .

(Другая подстановка >(list) также работает так, как вы ожидаете.)

В вашем конкретном случае вы могли бы использовать

program_expecting_a_file <(echo "$your_strings")

хотя вы можете найти решение @ meuh более элегантным.

Обновление: в руководстве по расширенному написанию сценариев Bash можно найти множество примеров использования.

11

Вы можете использовать bash здесь-док. Например,

$ cat -n <<<'a
> b'
 1  a
 2  b

Если у вас есть что-то в переменной bash, вы также можете интерполировать это: например, <<<"path is $PATH" .


Если ваша команда настаивает на имени файла, вы можете указать его /dev/stdin . Например:

$ sed -f /dev/stdin <<<'s/a/b/'

производит вывод: s/b/b/ .

7

В зависимости от того, что в сценарии, вы можете использовать специальное имя файла - (минус), что означает stdin

$ mycmd -
Line 1
Line 2
^D

Другой способ, который может вам помочь, - это открыть файл /dev/fd/0 который снова обозначает stdin.

Третий вариант может заключаться в создании FIFO (First In First Out). Это похоже на файл, но у него два конца - вы пишете с одного конца и читаете с другого.

-- Process 1 --                  -- Process 2 --
$ mkfifo foo
$ cat foo
<waits>                          $ echo hello > foo
hello                            $
$ rm foo
3

Там еще один вариант похож на mycmd - решение, но даже для программ , которые не работают - а именно:

$ mycmd /dev/stdin
Line 1
Line 2
^D

Кажется, что /dev/stdin связан с ОС и работает для меня в Debian GNU/Linux, но я не уверен, где еще он будет работать.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .