Как запустить функции и локальные ресурсы через SSH в сценарии оболочки - PullRequest
0 голосов
/ 25 мая 2018

У меня есть файл сценария оболочки, подобный следующему:

#!/bin/bash

CONF_FILE="/tmp/settings.conf" #settings.conf contains OS_NAME="Caine Linux"
source $CONF_FILE

display_os_name() { echo "My OS is:" $OS_NAME }

#using the function locally works fine
display_os_name
#displays: My OS is: Caine Linux

#using the function on the remote host doesn't work
ssh user@host "$(declare -f); display_os_name"
#displays: My OS is:

Если я удаляю -f и использую только ssh user@host "$(declare); display_os_name", он работает, но отображает эти ошибки и предупреждения:

bash: line 10: BASHOPTS: readonly variable
bash: line 18: BASH_VERSINFO: readonly variable
bash: line 26: EUID: readonly variable
bash: line 55: PPID: readonly variable
bash: line 70: SHELLOPTS: readonly variable
bash: line 76: UID: readonly variable

Если я использую ssh user@host "$(declare); display_os_name >/dev/null" для подавления предупреждений, подавляется только вывод функции (Моя ОС: Caine Linux), а не предупреждений.

Есть ли способ запуска локальных функций вместе сисходные локальные файлы на удаленном хосте SSH?

1 Ответ

0 голосов
/ 25 мая 2018

Простой подход (если у вас локальная сторона Linux) - это использовать set -a для включения автоматического экспорта перед вашей командой source;скопировать /proc/self/environ на стандартный ввод;и разобрать его в набор переменных на удаленной стороне.

Поскольку BASHOPTS, EUID и т. д. не являются переменными среды, это позволяет избежать попыток их изменения.(Если бы вы выполняли рекомендации POSIX и использовали строчные имена для своих собственных переменных, вы могли бы даже пойти настолько далеко, чтобы полностью игнорировать все заглавные буквы).

set -a # enable export of all variables defined, **before** the source operation
source /tmp/settings.conf

import_env() {
  while IFS= read -r -d '' item; do
    printf -v "${item%%=*}" "%s" "${item#*=}" && export "$item"
  done
}

cat /proc/self/environ | ssh user@host "$(declare -f); import_env; display_os_name"

Еще прощеэто просто скопировать файл, который вы хотите получить по сети.

ssh user@host "$(declare -f); $(</tmp/settings.conf); display_os_name"
...