【发布时间】:2017-07-13 00:25:40
【问题描述】:
我在不扩展传入的参数时遇到了一些问题。
我的 shell 脚本 (scp_run.ksh) 在具有 3 个服务器的环境中运行 - 脚本的目标是将文件从服务器上的存档文件夹移动到运行此脚本的服务器的存档文件夹中。
我已经在./scp_run.ksh /server/path/to/archive 之类的示例中对此进行了测试,并且 shell 脚本成功地查看了服务器和 scp 在每个 /server/path/to/archive 中找到的文件并将它们移动到当前服务器 /server/path/到/存档
这就是事情变得混乱的地方:我不想使用硬编码的路径,而是使用像 $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/archive,因此在调用 SCP 命令时,它正在寻找从当前节点上的环境变量设置的文件夹路径,而不是在一个它正在寻找 scp 的来源。
例如:从服务器 1 运行它我看到它正在为服务器 2 执行 scp 命令,例如 /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 并回显 ${SOURCE_DIR} 但我无法让 $SOURCE_DIR 不立即评估 $SERVER_ARCHIVE。
我认为它类似于remote_var=$(ssh myuser@server_2_name 'printf $SOURCE_DIR'),但我认为在我当前的设置中,这个 $SOURCE_DIR 已经被评估为 /reports_1/archive 而不是设置为 $SERVER_ARCHIVE
【问题讨论】:
-
我们需要一组简单的代码,我们可以复制/粘贴来进行测试。我没有看到您在发布的代码中的任何位置都为 SERVER_ARCHIVE 设置了值(或使用该变量)。您是说远程服务器应该提供该值还是(只是)每个服务器将具有不同的值,具体取决于
${server}的值。 (为什么不通过您的代码全部使用小写变量。Posix 为系统变量保留大写字母)。请更新您的 Q,而不是在 cmets 中回复。祝您好运。 -
这不是真正的 ksh 问题,而是 scp 问题。您不是在传递变量,而是传递对变量的引用。
-
顺便说一句,对于 sftp,这在设计上是明确和有意不可能的——拥有一个完全独立的子系统处理 sftp 的部分价值在于该子系统只能访问一组有限的显式操作,并且该组操作不包括扩展或评估环境变量。相比之下, scp 更像是一个... ad-hoc 软件,没有那么明确,它确实利用了远程 shell,所以我不能说没有这是不可能的深入实施。但是,本质上,任何修复都将由实现指定。
标签: shell ssh environment-variables