2017-02-22 18 views
0

У меня возникли некоторые проблемы с не расширяющимся параметром я передаю в.использовать пульт дистанционного управления переменным окружения в пути Scp

Моего сценарий оболочки (scp_run.ksh) работает в среде с 3 Серверы- цели из script - перемещать файлы из архивных папок на серверах в папку архива сервера, на котором выполняется этот скрипт.

Я тестировал это в примере, например ./scp_run.ksh /server/path/to/archive, и скрипт оболочки успешно просматривает серверы, а scp - файлы, найденные в каждом/сервере/пути/в /, и перемещает их на текущие серверы/сервер/путь// archive

Вот где вещи становятся беспорядочными: я не хочу использовать hardcoded путь, кроме среды var, как $ SERVER_ARCHIVE. Эта переменная среды настраивается на каждом сервере, хотя для каждого сервера это несколько другой путь (из моего контроля). Пример.

Server 1 $SERVER_ARCHIVE= /reports_1/archive 
Server 2 $SERVER_ARCHIVE= /reports_2/archive 
Server 3 $SERVER_ARCHIVE= /reports_3/archive 

Когда я вызываю мой сценарий как ./scp_run.ksh $SERVER_ARCHIVE, кажется, мгновенно оценить параметр/reports_x/архив и поэтому при вызове SCP команды он ищет путь к папке, установленной из переменной окружения на текущем узле не на тот, на который он смотрит.

например: Запуск этого с сервера 1 я вижу, что он выполняет команду УПП для сервера 2 как /usr/bin/scp -p server_2_name:/reports_1/archive/my_file.dat /reports_1/archive/.

SOURCE_DIR=${1} 
... 
for server in "${prod_servers_array[@]}" 
do 
    if [[ ${server} != ${currserver} ]] 
    then 
     /usr/bin/scp -p ${server}:${SOURCE_DIR}/${SOURCE_FILES} ${SOURCE_DIR}/. 
    fi 
done 

Что я надеюсь, для этой команды SCP на самом деле передать/получить $ SERVER_ARCHIVE (или независимо от того, что я могу передать, с фактического сервера для использования. Таким образом, то правильное выполнение/оценка

/usr/bin/scp -p ${server}:${SOURCE_DIR}/${SOURCE_FILES} ${SOURCE_DIR}/.

при работе на сервере 1 и глядя на сервер 2 выглядит

/usr/bin/scp -p server_2_name:/reports_2/archive/my_file.dat /reports_1/archive/.

есть способ передать $ SERVER_ARCHIVE в качестве параметра $ {1} и не оценивать ли он полный путь?

Моя мысль заключается в том, что прямо перед моей командой scp мне нужно SSH до $ server и echo $ {SOURCE_DIR}, но мне трудно получить $ SOURCE_DIR, чтобы сразу не оценить $ SERVER_ARCHIVE.

Я думаю, что это будет что-то вроде remote_var=$(ssh [email protected]_2_name 'printf $SOURCE_DIR'), но я думаю, что в моей текущей настройки этого $ SOURCE_DIR уже оценивается в/reports_1/архив и не установлен в $ SERVER_ARCHIVE

+0

мы нужен простой набор кода, который мы можем скопировать/вставить для тестирования. Я не вижу, что вы установили значение для SERVER_ARCHIVE (или используйте эту переменную) в любом месте вашего опубликованного кода. Вы говорите, что удаленный сервер должен предоставить это значение ИЛИ (просто), что каждый сервер будет иметь другое значение, в зависимости от значения '$ {server}'. (Почему бы не использовать строчные переменные все по вашему коду. Верхний регистр зарезервирован Posix для системных переменных). Пожалуйста, обновите свой Q, а не ответьте в комментариях. Удачи. – shellter

+0

Это не вопрос ksh, это вопрос scp. Вы не передаете переменную, но передаете * ссылку на * переменную. –

+0

BTW, для sftp это явно и намеренно невозможно по дизайну - часть значения наличия полностью независимой обработки подсистемы sftp заключается в том, что эта подсистема имеет доступ только к ограниченному набору явных операций, а этот набор операций не включает расширения или оценки переменных среды. В отличие от этого, scp является скорее ... специальным программным обеспечением, которое не так хорошо определено, и оно * использует * отдачу от удаленной оболочки, поэтому я не могу сказать, что это невозможно, не врываясь в реализацию. Однако по своей природе любое исправление * будет * указано в спецификации реализации. –

ответ

1

В отличие от SFTP, SCP в значительной степени определяется реализацией - - это означает, что не существует официального документа протокола или спецификации, который бы определял, что есть и не поддерживается в прямом-совместимом виде.

Если мы пытаемся написать что-то, что не собирается ломаться в будущем, было бы безопаснее не зависеть от него.

Один из ваших попыток была в правильном направлении:

# this only evaluates SOURCE_DIR on the remote end due to the outer single-quotes 
remote_var=$(ssh [email protected]_2_name 'printf "%s\n" "$SOURCE_DIR"') 

Другой подход не использовать УПП на всех, но использовать SSH работает свой собственный код для трансфера:

source_dir=$1 
source_files=(a.txt b.txt) # set this yourself 
source_files_q=$(printf '%q ' "${source_files[@]}") 

copy_remote_files() { 
    local server=$1 
    # important: unlike a <<EOF heredoc, <<'EOF' prevents any local expansion 
    ssh "$server" "ksh -s $source_files_q" <<'EOF' 
    # source dotfiles, to ensure we pick up SOURCE_DIR 
    # modify for your actual dotfiles 
    for f in ~/.profile ~/.rc; do . "$f"; done 
    [[ $SOURCE_DIR ]] || { echo 'Unable to find remote $SOURCE_DIR' >&2; exit 1; } 

    cd "$SOURCE_DIR" || { echo "Unable to cd to $SOURCE_DIR" >&2; exit 1; } 

    exec tar -c -- "[email protected]" 
EOF 
} 

cd "$SOURCE_DIR" || { echo "Unable to cd to local SOURCE_DIR" >&2; exit 1; } 
for server in "${prod_servers_array[@]}"; do 
    if [[ ${server} != "${currserver}" ]]; then 
    copy_remote_files "$server" | tar -x 
    fi 
done 
Смежные вопросы