OpenSSHでシステムクリップボードコピースクリプト

前回までに、OpenSSH経由でほかのホストからWindowsのシステムクリップボードへテキストをコピーするためのサーバをPowerShellで作ってきた。次のスクリプトだ。

winclipserver.ps1

#========================================================================
# 特定のファイルに書き込まれたテキストをシステムクリップボードにコピーする
# 簡易サーバ
#========================================================================

#========================================================================
# テキストが書き込まれるファイル
#========================================================================
$clipbrdFilePath = "${HOME}/.wincmdserver_clip"

#========================================================================
# ファイルをチェックするインターバル時間[秒]
#========================================================================
$fileCheckInterval = 1.0

#========================================================================
# サーバのプロセスIDを書き込むファイル
#========================================================================
$pidFilePath = "${HOME}/.winclipserver_pid"

#========================================================================
# サーバのプロセスIDをファイルへ記録
#========================================================================
Write-Output $PID > $pidFilePath

#========================================================================
# テキストが書き込まれるファイルを初期化
#========================================================================
Write-Output $null > $clipbrdFilePath

#========================================================================
# テキストが書き込まれるファイルを監視し、テキストが書き込まれた場合に、
# テキストをシステムクリップボートへコピーしてからファイルをクリアする。
#========================================================================
while ($true) {
    # テキストファイルが存在し、かつ、中身があるときにシステムクリップ
    # ボードへコピーする
    if (Test-Path "$clipbrdFilePath") {

        if (0 -lt (Get-ChildItem "$clipbrdFilePath").Length) {

            # システムクリップボードへテキストをコピー
            cat "$clipbrdFilePath" | clip

            # ログ出力
            $timestamp = Get-Date -format "yyyy/MM/dd HH:mm:ss"
            $timestamp + " - copied to system clipboard"

            # ファイルの中身をクリア
            Clear-Content "$clipbrdFilePath"
        }
    }

    # 次のチェックまで指定秒間待機
    Start-Sleep $fileCheckInterval
}

OpenSSH経由でテキストデータを送り込むためにちょっとしたシェルスクリプトも作成した。次のスクリプトだ。

winclip

#!/bin/sh

if [ $# = "0" ]
then
        set "/dev/stdin"
fi

cat "$1" | ssh WindowsのIPアドレスまたはホスト名 'cat > ${HOME}/.wincmdserver_clip'

この2つのスクリプトで「ほかのホスト」→「Windowsのシステムクリップボード」へテキストをコピーするまでの動作を確認した。最後にこれをタスクスケジューラに組み込んで、ログオンと同時に自動的に機能するようにする。

サーバをタスクスケジューラに登録

こうした機能はWindowsにログオンしている間は自動的に機能していてほしい。こういった場合に利用できる機能は「タスクスケジューラ」だ。

  • タスクスケジューラ

    タスクスケジューラ

タスクスケジューラを起動したらメニューから「操作」→「タスクの作成…」を選択して、タスクを追加する。

  • タスクの作成

    タスクの作成

ここに今回目的とするタスクを組み立てていく。

タスクを組み立てる

まず、「全般」→「名前」にタスクの名前を入力する。自分が区別できるわかりやすい名前を入力しておく。

  • 「全般」→「名前」

    「全般」→「名前」

次に「トリガー」を追加し、ログオン時に自動的に起動するようにする。「新規」を押してトリガーを追加する。

  • 「トリガー」→「新規」

    「トリガー」→「新規」

最初はタスクの開始が「スケジュールに従う」になっているので、これを「ログオン時」に変更して「OK」を押す。

  • 新しいトリガー

    新しいトリガー

  • 新しいトリガー:「タスクの開始」→「ログオン時」→「OK」

    新しいトリガー:「タスクの開始」→「ログオン時」→「OK」

次にPowerShellスクリプトを起動するためのアクションを追加する。「操作」を選択し「新規」を選択する。

  • 「操作」→「新規」

    「操作」→「新規」

ここでは説明のためにPowerShell 7や作成したPowerShellスクリプト、ユーザーのホームディレクトリが次のパスだと仮定する。

パス 内容
PowerShell 7パス C:\Program Files\PowerShell\7\pwsh.exe
PowerShellスクリプトパス C:\Users\daichi\winclipserver.ps1
ユーザのホームディレクトリ C:\Users\daichi

「新しい操作」の各項目は次のようになっている。

  • 新しい操作

    新しい操作

先ほどのパスをベースに、それぞれの項目に次の値をはめこんでいく。この部分はユーザーごとに置き換えてもらえればと思う。

操作の編集 項目 内容
操作 プログラムの開始
プログラム/スクリプト "C:\Program Files\PowerShell\7\pwsh.exe"
引数の追加 Command "C:\Users\daichi\winclipserver.ps1"
開始 C:\Users\daichi
  • 新しい操作:それぞれの項目を入力→「OK」

    新しい操作:それぞれの項目を入力→「OK」

  • 操作:追加された操作を確認

    操作:追加された操作を確認

次に条件を変更する。デフォルトの条件は、次のようにPCをAC電源で使っているときにタスクを開始する設定になっているはずだ。

  • 条件

    条件

この機能はAC電源で動いていようがバッテリー駆動していようが使いたいので、次のように条件を変更する。

  • 条件:電源の条件を変更

    条件:電源の条件を変更

最近筆者は、PCの電源を落とすということはあまり行わない。せいぜいスリープモードにするくらいだ。しかし、タスクのデフォルト設定では3日間でタスクが終了してしまう。

  • 設定

    設定

そこで変更して、次のように自動的にプログラムが終了しないようにしておく。

  • タスクが自動的に終了しないように変更

    タスクが自動的に終了しないように変更

これでタスクの組み立ては完了だ。さっそく、PCを再起動して動作を確認してみよう。

動作を確認

PCを再起動してログオンすると、自動的に設定したPowerShellスクリプトが実行される。その状態で、ほかのホストからシェルスクリプトを使ってテキストデータをWindowsへ送り込んでみる。

  • UbuntuからWindowsへテキストデータを送り込み

    UbuntuからWindowsへテキストデータを送り込み

Windowsで動作しているPowerShellスクリプトのサーバが反応してテキストをシステムクリップボードへコピーしてくれる。これまでに確認した通りの動作だ。

  • PowerShellスクリプトサーバが反応

    PowerShellスクリプトサーバが反応

これでMacやLinuxといったほかのホストからWindowsのシステムクリップボードへ比較的簡単にコピーできるようになった。作成したPowerShellスクリプトは大したものではないのだが、その効果は意外と大きい。こういったツールを手軽に作れるのが、PowerShellの魅力の一つだ。