bash - 如何在 shell 脚本中通过 SSH 运行函数和本地资源
问题描述
我有一个这样的 shell 脚本文件:
#!/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 主机上运行本地功能和本地源文件?
解决方案
一种简单的方法(如果您的本地端是 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"
推荐阅读
- ruby-on-rails - MVC模型之外的PORO需要用户IP地址
- java - ArrivalEvent.java:6:错误:类 Event 中的构造函数事件不能应用于给定类型;
- java - Java15 fx15,使用 jpackage、maven、shaded 非模块化 .jar 运行良好!但安装运行 pkg - 应用程序说旧 JRE,java mongo 驱动程序异常
- windows-runtime - .NET 5、WinUI 3 和 WinRT API 可用于桌面应用程序
- python - Toggle tkinter window visibility
- google-cloud-platform - 使用 Google 网上论坛访问 BigQuery
- mysql - 如何在递归查询中按变量排序并返回正确的顺序?
- gcc - .scat 文件和 .ld 文件之间的区别
- java - 我怎样才能找到索引值,或者即使某个字符串存在于数组中
- sql - 包含不匹配记录的联接