我有一个像这样的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主机上与源本地文件一起运行本地功能?
答案 0 :(得分:1)
一种简单的方法(如果您的本地方是Linux)是使用set -a
在source
命令之前启用自动导出;在stdin上复制/proc/self/environ
;并将其解析为远程端的一组变量。
由于BASHOPTS
,EUID
等不是环境变量,因此可以避免尝试修改它们。 (如果您遵守POSIX recommendations并使用小写名称作为自己的变量,您甚至可以完全忽略全部大写变量。)
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"