Lo primero que hay que entender en este proceso es cómo ssh maneja sus argumentos. No me refiero a los argumentos de lo que estás tratando de ejecutar, sino a los argumentos de ssh. Cuando invoca ssh
, los argumentos después de la especificación del host remoto(user@server
)se concatenan y se pasan a través del shell en el extremo remoto. Es importante tener esto en cuenta, ya que el hecho de que sus argumentos se dividan correctamente en el lado local no significa que se dividirán correctamente en el lado remoto.
Para usar su ejemplo:
ssh user@server 'echo "hello $1"' sh "world"
Estos argumentos se concatenan como el comando:
echo "hello $1" sh world
Por eso obtienes
hello sh world
El doble espacio entre hello
y sh
se debe a que allí es donde se suponía que debía ir $1
, pero no hay $1
.
Otro ejemplo, sin $1
, es:
ssh user@server echo "foo bar" baz
Lo que resulta en la salida:
foo bar baz
Esto se debe a que los argumentos se concatenan juntos, por lo que termina con el comando:
echo foo bar baz
Dado que no hay forma de eludir el comando que se pasa a través de un shell, solo debe asegurarse de que lo que pasó pueda sobrevivir a la evaluación del shell. La forma en que suelo lograr esto es conprintf "%q "
Por ejemplo:
cmd=(echo "foo bar" baz)
ssh user@server "$(printf "%q " "${cmd[@]}")"
Lo que resulta en la salida:
foo bar baz
Si bien es más limpio y más fácil de entender con cmd
siendo una var separada, no es obligatorio.Lo siguiente funciona igual:
ssh user@server "$(printf "%q " echo "foo bar" baz)"
Esto también funciona bien con su ejemplo de argumento de shell:
cmd=(sh -c 'echo 1="<$1>" 2="<$2>" 3="<$3>"' sh "my arg1" "my arg2" "my arg3")
ssh user@server "$(printf "%q " "${cmd[@]}")"
Lo que resulta en la salida:
1=<my arg1> 2=<my arg2> 3=<my arg3>
Como solución alternativa, puede pasar su comando como un script de shell completo. Por ejemplo:
ssh user@server <<'EOF'
sh -c 'echo 1="<$1>" 2="<$2>" 3="<$3>"' sh "my arg1" "my arg2" "my arg3"
EOF
Sin embargo, hay inconvenientes en esta solución, ya que es más difícil hacerlo programáticamente (generando el documento para transmitir STDIN ). Además, debido a que está utilizando STDIN, si desea que el script en el lado remoto lea STDIN, no puede (al menos no sin algunos trucos ).
Вы не можете связать набор двоичных файлов из каталога, но вы можете связать несколько альтернатив:
update-alternatives --install /usr/bin/A A /path/to/version1.0/bin/A 1 \
--slave /usr/bin/B B /path/to/version1.0/bin/B \
--slave /usr/bin/C C /path/to/version1.0/bin/C
Второстепенные альтернативы не взвешиваются, поскольку их выбор зависит только от выбора основной. Переключение альтернативы для A
приведет к переключению альтернатив для B
и C
в соответствии с ними.
Вы можете перечислить все двоичные файлы в /path/to/versionX/bin
и построить соответствующую командную строку, чтобы автоматически распространить это на все двоичные файлы...
Я вижу как минимум 3 варианта.
Настройте несколько каталогов с файлами
mystuff/A/bin1
mystuff/A/bin2
mystuff/A/bin3
mystuff/B/bin1
mystuff/B/bin2
mystuff/B/bin3
mystuff/active → mystuff/A
(или В)
Затем используйте альтернативы обновления -, чтобы указать наmystuff/active
Затем вы можете переключиться, обновив ссылку sym -.