在scp路径中使用远程环境变量的值 [英] Use remote environment variable's value in scp path

查看:719
本文介绍了在scp路径中使用远程环境变量的值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在不扩展我传入的参数方面遇到麻烦.

I am having some trouble with not expanding a parameter I am passing in.

我的shell脚本(scp_run.ksh)在具有3台服务器的环境中运行-该脚本的目标是将文件从服务器上的存档文件夹移动到运行此脚本的服务器的存档文件夹中.

My shell script (scp_run.ksh) runs in an environment with 3 servers- the goal of the script is to move files from the archive folders on the servers to the archive folder of the server running this script.

我已经在例如./scp_run.ksh /server/path/to/archive的示例中对此进行了测试,并且shell脚本成功查看了服务器,并scp了每个/server/path/to/archive中找到的文件,并将它们移至当前服务器/server/path/到/存档

I have tested this in an example like ./scp_run.ksh /server/path/to/archive and the shell script successfully looks across the servers and scp's the files found in each /server/path/to/archive and moves them to the current servers /server/path/to/archive

在这里事情变得一团糟:我不想使用硬编码的路径,而是使用像$ SERVER_ARCHIVE这样的环境变量.在每台服务器上都设置了此环境变量-尽管对于每台服务器,它的路径略有不同(超出我的控制范围). 例

Here is where things get messy: I want to not use a hardcoded path but an environment var like $SERVER_ARCHIVE. This environment variable is set up on each server - though for each server it is a slightly different path (out of my control). Ex.

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/archive,因此,在调用SCP命令时,它正在从当前节点上的环境变量而不是在它正在寻找从中提取的一种.

When I call my script like ./scp_run.ksh $SERVER_ARCHIVE it seems to instantly evaluate the parameter to /reports_x/archive and so when calling the SCP command it is looking for the folder path set from the environment variable on the current node not on the one it is looking to scp from.

ex:从服务器1运行此命令我看到它正在像/usr/bin/scp -p server_2_name:/reports_1/archive/my_file.dat /reports_1/archive/.

ex: Running this from Server 1 I see that it is executing the scp command for Server 2 like /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(或我传递的任何环境变量)以供使用.因此,正确的执行/评估

What I am hoping is for that SCP command to actually pass/get the $SERVER_ARCHIVE (or whatever env varible I pass) from the actual server to use. So then the correct execution/evaluation of

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

在服务器1上运行并查看服务器2时

when running on Server 1 and looking at Server 2 looks like

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

是否有一种方法可以将$ SERVER_ARCHIVE作为参数传递给$ {1}并使其不求值完整路径?

Is there a way to pass $SERVER_ARCHIVE as a parameter to ${1} and have it not evaluate to the full path?

我的想法是,在我的scp命令之前,我需要SSH到$ server并回显$ {SOURCE_DIR},但是我很难让$ SOURCE_DIR不能立即评估$ SERVER_ARCHIVE.

My thought is that right before my scp command I need to SSH over to the $server and echo ${SOURCE_DIR} but I am having trouble getting $SOURCE_DIR to not evaluate the $SERVER_ARCHIVE right away.

我认为它类似于remote_var=$(ssh myuser@server_2_name 'printf $SOURCE_DIR'),但我认为在我的当前设置中,此$ SOURCE_DIR已被评估为/reports_1/archive且未设置为$ SERVER_ARCHIVE

I think it would be something like remote_var=$(ssh myuser@server_2_name 'printf $SOURCE_DIR') but I think in my current setup this $SOURCE_DIR is already evaluated to /reports_1/archive and NOT set as $SERVER_ARCHIVE

推荐答案

与SFTP不同,SCP在很大程度上是实现定义的-意味着没有正式的协议文档或规范可以确定协议中支持和不支持的内容.前向兼容方式.

Unlike SFTP, SCP is largely implementation-defined -- meaning that there is no formal protocol document or specification that would determine what is and isn't supported in a forward-compatible way.

如果我们试图编写将来不会中断的内容,那么不依赖它会更安全.

If we're trying to write something that isn't going to break in the future, it would be safer not to depend on it.

您的尝试之一是朝正确的方向:

One of your attempts was in the right direction:

# this only evaluates SOURCE_DIR on the remote end due to the outer single-quotes
remote_var=$(ssh myuser@server_2_name 'printf "%s\n" "$SOURCE_DIR"')

另一种方法是根本不使用SCP,而是使用运行您自己的代码的SSH进行传输:

Another approach is not to use SCP at all, but to use SSH running your own code for the transfer:

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 -- "$@"
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

这篇关于在scp路径中使用远程环境变量的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆