我曾试图自己完成这项任务,但是在脚本登录到远程机器后,脚本就停止了。这很容易理解,因为远程机器不知道这个脚本的存在。但是,是否有办法解决这个问题呢?
谢谢。
ssh user@remote << 'END_OF_COMMANDS'
echo all this will be executed remotely
user=$(whoami)
echo I am $user
pwd
END_OF_COMMANDS
当你说“继续在那里做事”时,你可能是指简单地与远程会话进行交互,那么:
expect -c 'spawn ssh user@host; interact'
在这种情况下,我更喜欢使用Perl:
use Net::SSH::Perl;
my $ssh = Net::SSH::Perl->new($host);
$ssh->login($user, $pass);
my($stdout, $stderr, $exit) = $ssh->cmd($cmd);
使用它可以减少错误,更好地控制捕获命令的stdout、stderr和退出状态。
您需要在ssh调用的末尾提供远程命令:
$ ssh user@remote somecommand
如果您需要执行一系列命令,那么编写脚本并将其复制到远程机器(例如使用scp
)并按照上述方法调用会更容易。
我通过使用declare -f将整个函数通过ssh传递到远程服务器并在那里执行来解决了这个问题。这实际上可以非常简单地完成。唯一的注意事项是,您必须确保函数使用的任何变量都在其中定义或作为参数传递。如果您的函数使用任何环境变量、别名、其他函数或任何其他在其外部定义的变量,则它将无法在远程机器上运行,因为这些定义在那里不存在。
所以,这就是我做的方式:
somefunction() {
host=$1
user=$2
echo "I'm running a function remotely on $(hostname) that was sent from $host by $user"
}
ssh $someserver "$(declare -f somefunction);somefunction $(hostname) $(whoami)"
declare -f somefunction | perl -pe "s/(\\$)global_var/$global_var/g"
这将用变量的值替换函数中对global_var的任何引用。
干杯!
在你的~/.profile
(或者例如~/.bash_profile
)中加入类似以下内容即可:
function remote {
ssh -t -t -t user@remote_server "$*'"
}
然后调用
remote somecommandofyours