LoginSignup
9
12

More than 5 years have passed since last update.

リモートホスト上で、ローカルにあるスクリプトを動かす

Last updated at Posted at 2015-12-22

概要

bashやpythonのスクリプトを改変なしで、ファイルのコピーをせず、リモート実行する。

詳細

こんなスクリプトを動かしたい

sample.sh
#!/bin/bash

for arg in init ${@};do
    echo "$(date +%Y-%m-%dT%H:%M:%S) $(hostname) ${arg}"
    sleep 1
done
$ ./sample.sh a b c
2015-12-22T11:30:26 local-host init
2015-12-22T11:30:27 local-host a
2015-12-22T11:30:28 local-host b
2015-12-22T11:30:29 local-host c

基本的なアイデア

1. sshで、リモートのshellのstdinにスクリプトを投入できる。

$ cat sample.sh | ssh user@remote-host
2015-12-22T11:31:43 remote-host init

2. bashは、stdinの内容をファイルとして受け取れる

$ cat sample.sh | bash <(cat -) a b c
2015-12-22T11:33:47 local-host init
2015-12-22T11:33:48 local-host a
2015-12-22T11:33:49 local-host b
2015-12-22T11:33:50 local-host c

3. hereドキュメントを使えば、ファイルを作らなくてもスクリプト実行できる

$ cat << 'EOT' | bash <(cat -) a b c
> for arg in init ${@};do
>     echo "$(date +%Y-%m-%dT%H:%M:%S) $(hostname) ${arg}"
>     sleep 1
> done
> EOT
2015-12-22T11:40:17 local-host init
2015-12-22T11:40:18 local-host a
2015-12-22T11:40:19 local-host b
2015-12-22T11:40:20 local-host c

実装

こんなスクリプト

rdosh.sh
#!/bin/bash
echo -e "cat << 'EOT' | bash <(cat -) ${@:2}\n$(cat ${1}|sed -e 's/\\/\\\\/g')\nEOT"
  • catしたままだと、\nなどがエスケープされるため、sedで\をエスケープする

実験

$ ./rdosh.sh sample.sh a b c | ssh user@remote-host
2015-12-22T11:42:48 remote-host init
2015-12-22T11:42:49 remote-host a
2015-12-22T11:42:50 remote-host b
2015-12-22T11:42:51 remote-host c

できた

pythonも

こんなスクリプト

sample.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
import os
import time
for arg in ["init"]+sys.argv[1:]:
    sys.stdout.write("{0} {1} {2}\n".format(time.strftime("%Y-%m-%dT%H:%M:%S"),os.uname()[1],arg))
    sys.stdout.flush()
    time.sleep(1)
rdopy.sh
#!/bin/bash
echo -e "cat << 'EOT' | python <(cat -) ${@:2}\n$(cat ${1}|sed -e 's/\\/\\\\/g')\nEOT"

pythonも動いた

$ ./sample.py a b c
2015-12-22T13:20:29 local-host init
2015-12-22T13:20:30 local-host a
2015-12-22T13:20:31 local-host b
2015-12-22T13:20:32 local-host c
$ ./rdopy sample.py a b c | ssh user@remote-host
2015-12-22T13:20:46 remote-host init
2015-12-22T13:20:47 remote-host a
2015-12-22T13:20:48 remote-host b
2015-12-22T13:20:49 remote-host c
9
12
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
12