Вопрос или проблема
У меня, в основном, такая же проблема, как описано (и решено) здесь на Stack Overflow.
Эта проблема заключается в том, что SCP к некоторым хостам, которые не поддерживают подсистему SFTP, работает только если я использую флаг -O
.
Однако, есть ли способ настроить это поведение по умолчанию?
Например, с помощью опции в ~/.ssh/config
?
Дело в том, что для ручного использования я могу просто использовать alias scp='scp -O'
, однако это не сработает в скриптах и не оболочечных действиях (таких как запуск плейбуков Ansible).
Я думаю, что вы не можете использовать ~/.ssh/config
для решения вашей проблемы, потому что этот файл предназначен для ssh
, а не для scp
. Правда, scp
использует ssh
под капотом, но -O
, который вы хотите принудить, является опцией строго для scp
, а не для ssh
.
Возможно, вы сможете достичь приемлемого результата с помощью оборачивающего скрипта. Вот этот скрипт:
#!/bin/sh
exec /usual/path/to/scp -O "$@"
Вам нужно использовать полный путь к реальному scp
. Сохраните скрипт под именем scp
в директории, которая находится раньше в вашем $PATH
, чем все остальные директории в $PATH
, содержащие другие (в практике: реальные) исполняемые файлы scp
. Создайте новую директорию и при необходимости отредактируйте ваш $PATH
. Убедитесь, что скрипт исполняемый (chmod +x scp
).
С этого момента любой процесс, который наследует ваш измененный $PATH
и пытается запустить scp
, будет запускать обертку вместо реального scp
. Обертка заменит себя на реальный scp
, который получит -O
вместе со всеми аргументами, переданными обертке. Таким образом, -O
будет автоматически внедрен.
Есть случаи, когда этот метод не может сработать:
-
Если процесс, вызывающий
scp
, использует$PATH
, который не является вашим измененным$PATH
, тогда он не найдет обертку и запустит реальныйscp
напрямую; следовательно,-O
не будет внедрен. По этой причине вы можете захотеть изменить$PATH
как можно более “глобально”. -
Если процесс явно вызывает
/usual/path/to/scp
, то очевидно, что он вызовет реальныйscp
напрямую, независимо от$PATH
; следовательно,-O
не будет внедрен.
$PATH
.scp
в другое местоположение.scp
./usual/path/to/scp
.Недостаток в том, что ваша операционная система при обновлении может заменить обертку на новую версию реального scp
. Эта ошибка не может произойти в методе с измененным $PATH
и неизмененным /usual/path/to/scp
.
С момента выхода OpenSSH 9.8 единственный способ выбрать протокол SCP с помощью scp
— это использовать -O
флаг.
Никакой файл конфигурации или что-то еще не участвует.
Таким образом, все решения должны быть внешними для scp
. Например, с использованием алиаса.
Вот простой оберточный скрипт, который должен работать, независимо от того, требует ли целевой хост устаревший -O
флаг или нет. Он пытается подключиться без него, и если это не удается, пробует с флагом -O
(если он еще не пробовался).
#!/bin/sh
if ! /usr/bin/scp "$@"; then
[ $# -gt 0 ] || exit
for a; do [ "$a" = '-O' ] && exit 2; done
echo >&2 "переход в режим совместимости (-O)"
/usr/bin/scp -O "$@"
fi
Я предлагаю назвать его scp_safe
и поместить в ваш $PATH
где-нибудь.
Ответ или решение
Для решения проблемы с использованием параметра -O
в scp
, который необходим для работы с хостами, не поддерживающими SFTP, вы не сможете настроить это поведение по умолчанию напрямую через файл конфигурации ~/.ssh/config
. Этот файл предназначен исключительно для параметров ssh
, а scp
, хотя и использует ssh
под капотом, не позволяет задать параметр -O
в конфигурации.
Однако, вы можете создать обертку для scp
, которая будет автоматически добавлять нужный параметр. Вот шаги, которые необходимо выполнить:
- Создайте скрипт обертки для
scp
:
#!/bin/sh
if ! /usr/bin/scp "$@"; then
[ $# -gt 0 ] || exit
for a; do [ "$a" = '-O' ] && exit 2; done
echo >&2 "переход на совместимый режим (-O)"
/usr/bin/scp -O "$@"
fi
-
Сохраните этот скрипт, например, под именем
scp_safe
. Убедитесь, что вы указываете полный путь к оригинальномуscp
(/usr/bin/scp в данном примере, измените его при необходимости). -
Сделайте скрипт исполняемым:
chmod +x /путь/к/вашему/scp_safe
- Поместите этот скрипт в директорию, которая стоит выше по пути (
$PATH
), чем оригинальныйscp
, или изменитеPATH
, чтобы он использовал ваш скрипт:
export PATH="/путь/к/директории/с/scp_safe:$PATH"
Теперь, когда любой процесс будет пытаться вызвать scp
, он будет вызывать ваш скрипт обертки. Скрипт сначала попытается выполнить команду без параметра -O
, и если она завершится неудачей, то попробует снова с этим параметром, если он еще не был использован.
Таким образом, ваши сценарии и автоматизированные процессы, такие как Ansible, смогут использовать scp_safe
, что позволит избежать необходимости вручную добавлять -O
.
Важно
Имейте в виду, что если вас интересуют другие случаи использования scp
, важно следить за тем, чтобы процесс, вызывающий scp
, использовал модифицированный $PATH
, чтобы гарантировать, что используется именно обертка, а не оригинал.