При подключении к хосту с SSH, как правило , три «труба» предусмотрена между хостом и гостем, для stdin
, stdout
и stderr
.
Есть ли опция командной строки для создания пересылок для дополнительных файловых дескрипторов ( 3
и далее)?
Например, я хотел бы сделать
ssh --forwardfd=10:3 remotehost 'echo test >&3'
который напечатал бы 'test' в локально открытый дескриптор файла 10.
ssh
pipe
file-descriptors
мышей
источник
источник
closefrom(STDERR_FILENO + 1)
вызовы из исходного кода OpenSSH. Что вы пытаетесь сделать, что требует этого?stdin
/out
/err
, но, AFAIK, ни один сервер / клиент никоим образом не поддерживает эту функцию.infinite-output-cmd | ssh user@host bash /proc/self/fd/3 3< local-script-to-execute-remotely.sh
--forwardfd
даже не нужно.ssh
может проверить дескрипторы открытого файла перед открытием любой другой вещи и автоматически переслать их в те же дескрипторы файла на удаленной стороне. Это может быть абсолютно прозрачно, как мой пример. Интересно, насколько сложно было бы залататьssh
за это. Как вы сказали, это может быть сложно в зависимости от причин этогоclosefrom(STDERR_FILENO + 1)
.Ответы:
Вы можете сделать это, используя переадресацию сокетов, которая доступна начиная с openssh-6.7. Это какая-то труба. Этот метод описан, например, здесь: http://www.25thandclement.com/~william/projects/streamlocal.html
Вы получите двухсторонний маршрут для ваших данных. Вот пример с mysql:
источник
Я уверен, что это должно быть возможно. Я могу только предложить взломать, когда вы используете дополнительные ssh-соединения, чтобы каждый переносил другую пару файловых дескрипторов. Например, следующий сценарий проверки концепции делает первый ssh для запуска фиктивной команды (sleep) для подключения локальных fds 5 и 6 к удаленным stdin и stdout, предполагая, что эти fds вы хотите добавить к обычному 0,1, 2.
Затем выполняется настоящий ssh, и на удаленном компьютере он соединяет удаленные fds 5 и 6 со стандартным и стандартным sdin другого ssh.
Как пример, этот скрипт передает man-страницу в формате gzipped на удаленный компьютер, который распаковывает и запускает ее через man. Stdin и stdout реального ssh по-прежнему доступны для других целей.
источник
Проблема с ответом @jakuje: он работает только с сокетами , но вы не можете использовать стандартные инструменты UNIX, ожидающие файлы с ними:
ssh -R/tmp/sock.remote:/tmp/sock.local "$HOST" 'LANG=C cat >/tmp/sock.remote'
Также есть проблема, что локальный файл сокета не удален на удаленном хосте; когда вы в следующий раз выполните ту же команду, вы получите предупреждение, и сокет не будет воссоздан правильно. Вы можете дать возможность ,
-o StreamLocalBindUnlink=yes
чтобыssh
в разкомпоновать , что старый сокет, но в моих тестах не было достаточно; Вы также должны отредактировать вас,sshd_config
чтобы содержать,StreamLocalBindUnlink=yes
чтобы эта опция работала.Но вы можете использовать
socat
илиnetcat
или любой другой подобный инструмент поддержки UNIX локальных сокетов (netcat-traditional
это НЕ достаточно!) , Чтобы использовать перенаправление локального сокета для передачи файлов:Вы также можете запускать интерактивные команды, в этом случае вы должны использовать
ssh -t
для выделения TTY.Проблема с этим решением состоит в том, что вы должны жестко закодировать пути локальных сокетов UNIX: локально это не такая большая проблема, как вы можете включить
$$
в путь, чтобы сделать его уникальным для процесса или пользователя во временном каталоге, но в удаленный конец, вам лучше не использовать каталог для записи в мире,/tmp/
как я делаю в моем примере. Каталог также должен существовать приssh
запуске сеанса. И inode сокета останется даже после закрытия сеанса, поэтому использование что-то вроде "$ HOME / .ssh. $$" будет загромождать ваш каталог мертвыми inode с течением времени.Вы также можете использовать привязанные к TCP-сокеты
localhost
, что избавит вас от загромождения файловых систем мертвыми inode, но даже с ними вам все равно придется выбирать (уникальный) неиспользуемый номер порта. Так что до сих пор не идеал. (ssh
имеет код для динамического распределения портов, но я не нашел способа получить эту информацию на удаленном хосте.)Вероятно, самое простое решение для копирования файлов - использовать встроенную функцию обмена соединениями в ssh и выполнить команду
scp
или,sfrp
пока интерактивный сеанс все еще работает параллельно. См. Скопируйте файл обратно в локальную систему с помощью ssh .источник