wet-to-dry’s blog

京大大学院生の備忘録ブログ

研究室のPCに画面共有する話

目次

概要

以前の話

wet-to-dry.hatenablog.com

wet-to-dry.hatenablog.com

以前は京都大学VPN接続するまでをやりました。

今回は画面共有の方法です。

やったこと

VPNでローカル接続されたPC同士で、画面共有を行う方法です。

画面共有のできる有名なアプリで

  1. chrome リモートデスクトップ

  2. Microsoft リモートデスクトップ

  3. TeamViewer

  4. ultraVNC

などがあります。参考↓

it-trend.jp

結論から言いますと、現在はTeamViewerがNo. 1ultraVNCがNo. 2かなと思います。

共有のスムーズさでは、TeamViewerがダントツでした。ほかは似たり寄ったりです。

Microsoft リモートデスクトップはWindows10 ProのPCを持っていないとだめです。Chrome リモートデスクトップは可もなく不可もなくです。UltraVNCは、以下に書きましたが、ローカルLAN内での接続ができるため、よりセキュアな対応ができます。

TeamViewerでいいのではないかという感じなのですが、まれに商用利用を疑われてアカウントを停止されることがあるそうです。Windows Education使っている人は一定数いるんじゃないでしょうか?

teikokutyo.com

UltraVNCはTeamViewerが商用利用でBANされた時用の予備という認識です。

0. P2P (pear to pear)通信について

ここで一つ言っておかなければいけないことがあります。

多くの大学ではP2P技術を用いた外部との接続は許可されていません。

www.cii.u-fukui.ac.jp

P2Pの危険性についてはWikipediaがわかりやすいです。

ja.wikipedia.org

P2P技術を使っていても、ファイルを不特定多数に公開することのないソフトも多く存在します。

(例)Skype, Google Drive, Dropboxなど

京都大学では比較的規制が緩く、P2P技術を使用していても上記のようにファイル自動公衆送信機能を持たないソフトであればしようが許可されています。

www.iimc.kyoto-u.ac.jp

Chrome リモートデスクトップは"P2P技術をがっつり使っている"らしいです。

medium.com

TeamViewerは狭義のP2Pには該当しないとコミュニティで指摘されています。

community.teamviewer.com

しかし同じ記事の中で、広義のP2P(1:1で通信するソフト)には該当するともいわれているため、大学によっては制限しているところもあるかと思います。

他大学で、TeamViewerが制限もしくは禁止されている場所では、TeamViewer内のインターネットへの接続をオフにすることでローカルLAN内で接続することができます。

community.teamviewer.com

また、ultraVNCもP2Pらしいです。

ameblo.jp

なんかよくわかんなくなってきました(笑)

ultraVNCはIPアドレスを指定してつながなければいけないので、ChromeリモートデスクトップやTeamViewerとは少し異なるのだと思います。

とりあえず、前回の記事のように、VPNで学内LANに接続した後にローカルLAN内でTeamViewerやultraVNCでローカル接続すれば、「P2P技術を使っていない」とみなせるのではないでしょうか?

1. TeamViewerの使い方

インストールと使用方法自体はそんなに難しくありません。

心配な方は、こちらの記事を読んでください。

michisugara.jp

TeamViewerのページに飛んで、インストーラーをダウンロードし、実行すればOKです。

このままでは、リモートPCを長時間放置した時にスリープに入ってしまい、帰宅してからつなごうとしてもつなげません。

よって、Windows10の場合はスリープをOFFにしてください。参考↓

dekiru.net

「ディスプレイの電源を切る」はONにしておいても大丈夫です。

ディスプレイの電源が落ちても、リモート接続すれば自動でついてくれます。

2. ultraVNCの使い方

使い方は以下の通り。

pcmanabu.com

窓の杜からUltraVNCインストーラーをダウンロードし、手順に沿ってインストールしていきます。

一つ注意点は、リモート接続される側のPCはUltraVNC Serverを、リモート接続する側のPCはUltraVNC Viewerを選択して入れないといけないところくらいでしょうか。

僕は

される側・・・Server, Viewer, Repeater

する側・・・Viewerのみ

をインストールしました。

また、desktop duplicationをオンにするとよいという知見も得たので、UltraVNC Serverのプロパティからdesktop duplicationのチェックをつける!

kulog.org

あんまり体感として速くはなってないかも、、、

まあ、いいか。

あとがき

ちなみに、TeamViewerならUbuntuPCもWindowsと同様にセットアップすることができます。

community.teamviewer.com

Ubuntuを起動したときに自動でTeamViewerが起動するように設定をしておくと、毎回起動操作をしなくていいので少し楽です。

blog.goo.ne.jp

また、ultraVNCはUbuntuには必要ないらしく、デフォルトでVNC接続が可能らしいです。

ただ、設定は少し必要です。

https://www.yokoweb.net/2019/12/09/ubuntu-18_04-desktop-vnc-remote/www.yokoweb.net

まずubuntuの設定を開き、共有タブをクリック。右上のオフと出ているスライドボタンをオンにする。

f:id:wet-to-dry:20200421174207j:plain

次に画面共有(S)と書かれているところをクリックすると新しいポップアップが出るので、これもオンにしてパスワードを設定する。ネットワークの欄も、オフになっていればオンにする。

f:id:wet-to-dry:20200421174204j:plain

設定はこれで終わり。あとは以下のコマンドをターミナルに入力し、PCを再起動しましょう。

sudo gsettings set org.gnome.Vino require-encryption false

これでつながるはず!!!

続編 (2020/07/16追記)

Anydeskなるソフトを教えてもらいました。

TeamViewerの上位互換かな?ってくらい良かったので、こちらを使うことにしました。

メリットデメリットは記事を読んでね!

wet-to-dry.hatenablog.com

研究室のPCにSSH接続する話2

目次

概要

以前の話

wet-to-dry.hatenablog.com

前回はサーバーPCからサーバーPCに向けてSSH接続をしましたが、今回はクライアントPCからサーバーPCに向けてSSH接続を試みます。

やったこと

京大のネットワークはKUINSと呼ばれており、学外公開に対応しているKUINS-IIと学外公開が難しいKUINS-IIIの二種類があります。

www.iimc.kyoto-u.ac.jp

KUINS-IIの場合はおそらくSSH接続ではポートフォワーディングが必要です(確証はないです)。

www.iimc.kyoto-u.ac.jp

www.ketsuago.com

KUINS-IIIの場合は、IKEv2と呼ばれるVPN接続をすればいけるらしいです(これは研究室のネットワーク管理者が、KUINS管理者にVPN接続したい人のESC-IDを申請しないとできません)。

www.iimc.kyoto-u.ac.jp

僕の研究室はKUINS-IIIなので、VPN接続でまずラボのLANに入り、そこからsshを飛ばすことになりそうです。

やらなければいけないのは以下の通り。

  1. ネットワーク管理者VPN接続申請をしてもらう

  2. VPN接続設定

0. Windows PowerShell の文字化けについて

前回、sshをするとWindows PowerShell内で文字化けが発生してしまう問題がありました。

ネットには文字コードを変更しろだの色々書いてありましたが、そもそもWindowsSSH serverを使っている人が少なく、うまい解決策は乗っていませんでした。

しかし、一応の打開策(?)は見つかりました。

Windows PowerShellをデフォルトのアプリで開くのではなく、VSCodeアプリで開く

です。

根本的な解決策にはなっていませんが、PowerShellのアプリがダメダメだったってことですかね。。。

VSCodeのインストール、設定は以前まとめました。

wet-to-dry.hatenablog.com

VSCodeを立ち上げ、

ターミナル→新しいターミナル

で下部分にターミナルコンソールが出てくると思いますので、ここからPowerShellアプリと同じように操作しましょう。

1. ネットワーク管理者VPN接続申請をしてもらう

あまり書くことはないですが、ラボのネットワーク管理者(たぶん教授)に「VPN接続をしたいので申請していただけますか?」といえば伝わると思います。

新型コロナが猛威を振るうこのご時世ですので、ダメとは言われないと思います。

やり方は

  1. まずhttps://db.kuins.kyoto-u.ac.jp/にSPS-IDでログインしてもらう。

  2. 一番下の「変更を申請する」(?)をクリック

  3. 「KUINS-AirVPNでの接続を許可するID」の部分の横の「+」ボタンを押し、自分のECS-IDを入力してもらったあと、一番下の「申請する」(?)をクリック

  4. この時に、「VLAN管理番号」も教えてもらいましょう。この番号がVPN接続に必要です。

でいけるはずです。

ボスにやってもらったのでうろ覚えですが、そんなに難しい作業ではなかったです。

2. VPN接続設定

申請した翌日くらいに外部接続したいPCでVPN接続設定を行います(僕の場合はその日の夕方には使えた)。

このリンクのマニュアルを読みながらやりましょう↓

www.iimc.kyoto-u.ac.jp

僕はwindowsですが、そんなに難しくなかったです。

設定ができると、

f:id:wet-to-dry:20200410164834p:plain

こんな感じでタスクバー内のwifiアイコンからVPNが選べるようになります(ikev-North-VPNが今回設定したVPNです)。

ログインIDは「ECS-ID@VLAN管理番号」、パスワードはECS-IDのパスワードです。

VPN接続を行うと、Windows PowerShell

ping 10.226.122.1(サーバーPCのIPv4アドレス)

# 以下結果
10.226.122.1 に ping を送信しています 32 バイトのデータ:
10.226.122.1 からの応答: バイト数 =32 時間 =3ms TTL=128
10.226.122.1 からの応答: バイト数 =32 時間 <1ms TTL=128
10.226.122.1 からの応答: バイト数 =32 時間 <1ms TTL=128
10.226.122.1 からの応答: バイト数 =32 時間 <1ms TTL=128

10.226.122.1 の ping 統計:
    パケット数: 送信 = 4、受信 = 4、損失 = 0 (0% の損失)、
ラウンド トリップの概算時間 (ミリ秒):
    最小 = 0ms、最大 = 3ms、平均 = 0ms

で外部からでもサーバーPCにコネクトできる準備が整っていることがわかります。

ちなみにコネクトできていないときは、

ping 10.226.122.0

10.226.122.22 からの応答: 宛先ホストに到達できません。
10.226.122.22 からの応答: 宛先ホストに到達できません。
10.226.122.22 からの応答: 宛先ホストに到達できません。
10.226.122.22 からの応答: 宛先ホストに到達できません。

10.226.122.0 の ping 統計:
    パケット数: 送信 = 4、受信 = 4、損失 = 0 (0% の損失)

みたいな感じになります。


一応、sshで接続できるかどうかも確認しておきます。

ssh 10.226.122.1(サーバーPCのIPv4アドレス)

で、

Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

新しいクロスプラットフォームの PowerShell をお試しください https://aka.ms/pscore6

PS C:\Users\ユーザー名>

とコンソールが出てくればOKです。

exit

sshサーバーから出ることができます。

あとがき

毎回パスワードを打つのが面倒くさかったのでSSH鍵認証を導入したかったのですが、難しくて諦めました。

なにが難しいかというと、

  1. Windows OpenSSH Serverの公開鍵登録ディレクトリがどこかわからない(一応ホームディレクトリ/.sshらしい)

  2. SSH初心者なので、公開鍵、秘密鍵の正しいpermissionがわからない

  3. windowsでのpermissionの変更の仕方がわからない

です。

Linuxの記事は色々出てくるのですが、windowsはほとんどなかったし、少ない中で記事と同じ事やっても全然つながらない。

これはパスワード打った方が楽!ってなりました(笑)

まあ正直、リモートワークするにしてもSSH接続するのは解析用のUbuntu PCかなって思うので()、悔いは残りますが深追いはしないようにします。

次は画面共有かな~

追記(2020/10/09) 鍵認証

鍵認証ができたので、追記します。

まず、

$ ssh-keygen -t rsa #鍵作成
$ scp C:Users\*****\.ssh\id_rsa.pub *****@**.***.***.**:~/

二行目でWindowsの~/.sshに作成された公開鍵(id_rsa.pub)をリモートPC(Ubuntu)のホームディレクトリに送信しました。

scpコマンドはsshの回線を使ってファイルを送受信できるコマンドです。

*****@**.***.***.**sshで接続するリモートのアドレス。

で、

$ ssh *****@**.***.***.**

でリモートPCにssh接続して、

$ apt-get install openssh-server #openssh-serverを一応インストール
$ mkdir ~/.ssh
$ chmod 700 .ssh #おまじないでパーミッションを変更
$ mv ~/id_rsa.pub ~/.ssh/authorized_keys
$ chmod 600 .ssh/authorized_keys
$ exit

これでいけるはず!

パスワード認証を拒否して鍵認証のみにするには、/etc/ssh/sshd_configを開いて

PasswordAuthentication no

を入力すればOKらしいですが、僕はしてません(研究室のローカルLAN内でそこまでセキュリティを気にしてないので)。

ここを参考にしました↓

qiita.com

qiita.com

追記(2020/10/12) sshのconfig

めんどくさがりの僕は

ssh *****@**.***.***.**

を打つのもめんどくさいので、sshのconfigファイルをいじってコマンドを短くしました。

~/.ssh/にファイル名「config」で

Host hoge #自分がsshの後に打ちたいコマンド(例でhoge)
HostName **.***.***.** #@マークの後に打つIPアドレス
User ***** #@マークの前に打つユーザー名
Port 22
IdentityFile C:\\Users\\*****\\.ssh\\id_rsa #sshの秘密鍵の場所

というファイルを作成。

ssh hoge

で簡単につなげるようになった。

参考記事↓

qiita.com

webkaru.net

実験マウスを管理するための専用フォームを開発する4

概要

以前から「マウス管理システム」なるものをちょくちょく作っています。

wet-to-dry.hatenablog.com

wet-to-dry.hatenablog.com

wet-to-dry.hatenablog.com

これを、さらに変更しました。

変更点としては、

一番てこずりました。。。コツはwithSuccessHandlerの使い方でしたね。

  • マウスが生まれた際の入力ページに、0から10の選択肢を作成する関数をjavascriptで作成した

0から10までoptionタグ作ってるのがダサかったので。

  • index.htmlを「マウスが生まれた」と「マウスを屠殺した」に分岐させるだけのページにして、遷移先のページで実際の値を入力するようにした

これでやれることが一気に増えます。

できたもの

以下のサイトを参考にしました。

qiita.com

スプレッドシートは引き続き以下のものを使用している(URL共有済み)

docs.google.com

コードもいっそ共有してしまおう!

script.google.com

一応コードを下に書きます

main.js

var id = "1HuaAdg-xdo6n_JJXCYgyzD8bAHjl09ngtJbVwF8SXNw";

// htmlからhtmlへの遷移用。"https://surleconomiejp.blogspot.com/2017/02/google-apps-script-htmlhtml.html"を参考にした。
function doGet(e) {
  if (!e.parameter.page) {
    return HtmlService.createTemplateFromFile('index').evaluate();
  }
  return HtmlService.createTemplateFromFile(e.parameter['page']).evaluate();
}

// htmlからhtmlへの遷移用。"https://surleconomiejp.blogspot.com/2017/02/google-apps-script-htmlhtml.html"を参考にした。
function getScriptUrl() {
  var url = ScriptApp.getService().getUrl();
  return url;
}

// cssやjavascriptの外部ファイルを読み込むための関数。"https://qiita.com/taromorimotohf/items/5e52cb9062600e8ccac3"を参考にした。
function include(filename) {
  return HtmlService.createHtmlOutputFromFile(filename).getContent();
}

//スプレッドシートのデータを格納。"https://qiita.com/non-programmer/items/e822dbeb7b3ab6e403b3"を参考にした。
function loading(sheetname) {
  var ss = SpreadsheetApp.openById(id);
  var listss = ss.getSheetByName(sheetname);
  //最終行を調べる
  var lastrow = listss.getLastRow();
  //2行1列目最終行3列目までを二次元配列に入れています。
  var list = listss.getRange(2, 1, lastrow-1, 3).getValues();
  //時間要素をplane textに直す
  for (var i=0; i<list.length; i++){
    var date = list[i][1];
    var dateString = Utilities.formatDate(date,"JST","yyyy/MM/dd");
    list[i].splice(1, 1, dateString); 
  }
  return list;
}

// spreadsheetからデータを削除するための関数。
function delete_from_sheet_gs(sheetname, value) {
  var ss = SpreadsheetApp.openById(id);
  var listss = ss.getSheetByName(sheetname);
  listss.deleteRows(Number(value) + 2);
}

// spreadsheetにhtmlから直接書き込むための関数。"https://www.pre-practice.net/2017/10/web.html"を参考にした。
function input_to_sheet_gs(sheetname, value) {
  // 日時をYYYY//MM//DDの形式に変更
  var dt = new Date();
  var y = dt.getFullYear();
  var m = ("00" + (dt.getMonth() + 1)).slice(-2);
  var d = ("00" + dt.getDate()).slice(-2);
  var time = y + "/" + m + "/" + d;
  
  var ss = SpreadsheetApp.openById(id)
  var sh = ss.getSheetByName(sheetname);
  
  var lastRow = sh.getLastRow() + 1;
  sh.getRange(lastRow, 1, 1, 2).setValues([[value, time]]);
  sh.getRange(lastRow, 3).setFormulaR1C1("=ROUNDDOWN((TODAY()-R" + lastRow + "C2)/7)");
}

index.html

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <base target="_top" />
    <?!= include('css'); ?>
    <!---html間の遷移用--->
    <?var url = getScriptUrl();?>
  </head>
  <body>
    <h1>マウス管理フォーム</h1>
    <button onclick="window.top.location.href='<?!=url?>?page=born_mouse'">生まれた</button><br>
    <button onclick="window.top.location.href='<?!=url?>?page=slaughter_mouse'">屠殺した</button>
  </body>
</html>

result.html

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <?!= include('css'); ?>
    <?var url = getScriptUrl();?>
  </head>
  <body>
    <h1>マウス管理フォーム</h1>
    送信が完了しました。<br><br>
    
   <!---別のhtmlへの遷移は"https://surleconomiejp.blogspot.com/2017/02/google-apps-script-htmlhtml.html"を参考にした--->
   <button onclick="window.top.location.href='<?!=url?>?page=index'">もう一度回答する</button>
  </body>
</html>

born_mouse.html

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <base target="_top" />
    <?!= include('css'); ?>
    <?var url = getScriptUrl();?>
  </head>
  <body>
    <h1>マウス管理フォーム</h1>
    オスの匹数
    <select id="male">
    </select>
    <br>
    メスの匹数
    <select id="female">
    </select>
    <br>

    <button onclick="input_to_sheet();window.top.location.href='<?!=url?>?page=result'">送信する</button>
  </body>
  <?!= include('js_input_to_sheet'); ?>
</html>

slaughter_mouse.html

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <base target="_top" />
    <?!= include('css'); ?>
    <?var url = getScriptUrl();?>
  </head>
  <body>
    <h1>マウス管理フォーム</h1>
    使用したマウス
    <select id="sheetname" name="sheetname" onchange="loadsheet(this);" required>
      <option value="オス">オス</option>
      <option value="メス">メス</option>
    </select>
    <div id="information">
      <select id="list" name="list"></select>
    </div>
    <button id="submit" onclick="delete_from_sheet();window.top.location.href='<?!=url?>?page=result'">送信する</button>
  </body>
  <?!= include('js_list_from_sheet'); ?>
</html>

js_input_to_sheet.html

<script>
  function input_to_sheet() {
    let list = ["male", "female"];
    let sheetname = "";
    for (let i = 0; i < 2; i++) {
      if (i < 1) {
        sheetname = "オス";
      } else {
        sheetname = "メス";
      }
      let value = document.getElementById(list[i]).value;
      //valueが0の場合は入力しない
      if (value != 0){
        google.script.run.input_to_sheet_gs(sheetname, value);
      }
    }
    alert("スプレッドシートに入力しました!");
  }
  
  //selectの要素内に0から10までの選択肢を作成する関数。
  function add_options() {
    let list = ["male", "female"];
    for (let i = 0; i < list.length; i++) {
      let select = document.getElementById(list[i]);
      for (let j = 0; j <= 10; j++) {
        let option = document.createElement('option');
        option.setAttribute('value', j);
        option.innerHTML = j;
        select.appendChild(option);
      }
    }
  }
  
  add_options();
  
</script>

js_list_from_sheet.html

<script>
  //スプレッドシートの値をselectの要素に導入する関数。"https://qiita.com/non-programmer/items/e822dbeb7b3ab6e403b3"を参考にした。
  function loadsheet() {
    let sheetname = document.getElementById("sheetname").value;
    //.gs内のloading()を呼び出し、読み込み後にListBack()でselect要素に選択肢を設定します。
    google.script.run.withSuccessHandler(ListBack).loading(sheetname);
  }

  window.addEventListener('load', loadsheet());
 
  //リスト読み込み
  function ListBack(data) {
    let select = document.getElementById('list');
    //選択を変えたときに前回の情報が残らないようにする
    while (select.firstChild) {
      select.removeChild(select.firstChild);
    }
    for (let i=0; i<data.length; i++){
      let option = document.createElement('option');
      option.setAttribute('value', i);
      option.innerHTML = data[i][1] + "生まれ, " + data[i][0] + "匹, " + data[i][2] + "週齢";
      select.appendChild(option);
    }
  }

  function delete_from_sheet(){
    let sheetname = document.getElementById("sheetname").value;
    let value = document.getElementById("list").value;
    google.script.run.delete_from_sheet_gs(sheetname, value);
    alert("スプレッドシートから削除しました!");
  }
</script>

css.html

<style>
body{
background:#000;
color:#fff;
}
</style>

あとがき

コードが死ぬほど増えました。githubに移るべきか??

あとやりたいこととしては、屠殺したマウスをデータとして残すために、「処分マウス」シートを作りたいなあ。

交配をかけるためのページもつくりたい。

データの受け渡しなどの土台になることはほとんど調べ切ったと思うので、あとは地道に書くだけです!

頑張ろう!

2020/12/03追記

記事をまとめました。

wet-to-dry.hatenablog.com

タスクスケジューラでbatファイルを自動実行し、メッセージボックスを出して帰宅を促す

概要

パソコン作業してると、つい時間を忘れて23時まで作業してしまう、、、

翌日は6時から実験なのに!どうしよう!ってことありませんか???

僕はあります。

なので、安心と信頼のwindows君に帰宅管理してもらおうと思いました。

やることは簡単。アラートメッセージを出すbatファイルをどこかに保存しておいて、タスクスケジューラ*1で21:00とかに起動するようにしました。

目次

やったこと

メッセージボックスを出すbatファイルを作成する

このサイトを参考にした。

snjx.info

piyopiyocs.blog115.fc2.com

batファイルは以下の通り。

@echo off

if not "%HOGE%"=="hoge" (
    set HOGE=hoge
    start /min cmd /c,"%~0" %*
    exit
)

echo msgbox "21時になりました。",vbCritical,"時刻" > %TEMP%/msgboxtest.vbs & %TEMP%/msgboxtest.vbs

このファイルをkitaku.batという名前を付けて好きなディレクトリに保存。

また、最初は文字コードUTF-8になっててwindowsが読み込まなかったので、以下のサイトを参考にVSCodeでShift-JISに直した。

qiita.com

qiita.com

具体的には、files.autoGuessEncodingをチェックして文字コードを確認(右下のタブに出てくる)→タブのUTF-8をクリックしReopen with Encodingでshift-JISを選択

タスクスケジューラで定時にbatファイルを自動実行させる

このサイトを参考にした。

qiita.com

  1. Windowsキー&R
  2. taskschd.mscと打つ
  3. タスクスケジューラライブラリを右クリックし、新しいフォルダ(僕はMySchedule)を作成
  4. MyScheduleを右クリック→タスクの作成
  5. 名前: kitaku.batの実行、セキュリティオプションはログオンしているときのみ(一応、構成はwindows10にした)
  6. トリガータブで新規→自分の好きなスケジュールを作成(僕は1日1回、21:00)
  7. 操作タブで新規→操作はプログラムの開始、参照からさっき作ったbatファイルを選ぶ

あとがき

プロンプトを完全に表示させずにメッセージボックス出すのができなさそうだったので、最小化で妥協しました。

ならプロンプトにメッセージを表示すればよかったのでは、、、???

2023/08/08追記

batファイルじゃなくて途中で作成するvbsファイルを直接呼び出せばよかった。。。

下記のように変更しました。

1 msgboxtext.vbsという名前で以下を保存(VBSはShift-JIS以外にUTF16-LEも使えるらしいので、UTF16-LEにすれば絵文字も打てる)

msgbox "21時になりました。" & vbCr & "急いで帰りましょう!₍₍ ◝(•̀ㅂ•́)◟ ⁾⁾",vbCritical,"時刻"

2 タスクスケジューラでmsgboxtext.vbsを自動実行

*1:定時にプログラムを実行してくれるアプリ。デフォルトで入ってる。

WindowsのWSLでNGS解析するための準備2

目次

概要

今回のテーマは、

WSL上でホームディレクトリをOnedriveの共有ディレクトリに変更する

です。

以前、Windows10にWSL(Windows Subsystem for Linux)を導入する方法について紹介しました。

wet-to-dry.hatenablog.com

導入してからあまり弄れていなかったんですが、ふと久しぶりに前の記事を読み直したとき、

このホームディレクトリ、Windowsから探しづらくね???

となったので、ホームディレクトリをいつもお世話になっているOnedriveの共有ディレクトリに移しました。

やったこと

1. 前準備

まず、Onedrive for windowsは入れておいてください。

onedrive.live.com

これで、

C:\Users\username\OneDrive\

フォルダが共有フォルダとして作成されるはずです。

僕は京都大学のofficeアカウントを年間1320円で使っているので

www.s-coop.net

このアカウントの共有フォルダは

C:\Users\username\OneDrive - Kyoto University\

に入っています。*1

2. ホームディレクトリの設定

前回と同じく、

sudo vi /etc/passwd

でパスワードファイルを開き、最終行

username:x:1000:1000:"",,,:/home/username:/bin/bash ←初期設定
username:x:1000:1000:"",,,:/mnt/c/ubuntu:/bin/bash ←前回の記事

username:x:1000:1000:"",,,:/etc/c/Users/username/ONEDRI~1/xxx/xxx:/bin/bash

へと変更する

変更部分の「/etc/c/Users/username/」は名前の通り。また、「/xxx/xxx」は、僕が設定したpathをぼかしてるだけです。使いたいホームディレクトリになるようなpathにしてください。

windowsのpath「/OneDrive - Kyoto University/」には半角スペースが含まれているため、bashがうまく識別しない。*2

下記のサイトにもあるように、windowsにはショートファイルネームという表現技法があり、これを使えば何とかいけました。

okwave.jp

一応ここでも解説しておきます。

windowsには何文字でも使ってよいロングファイルネームと、8文字英数+拡張子3文字のショートファイルネームが存在しているらしいです。

そのため、「OneDrive - Kyoto University」のように8文字よりも長いファイル名(ロング)は、別名として「ONEDRI~1」という6文字+チルダ+番号のファイル名(ショート)が与えられているようです。

「OneDrive」は「ONEDRI~1」にはならなかったので、たぶん8文字以下のファイル名にはショート版は与えられないのかな?

とりあえず、書き換えた後に:wqで保存してexit→もう一度WSLを再起動

pwd

で、ちゃんとパス通りにホームディレクトリが設定されていることがわかります。

あとがき

以前、ショートファイルネームどこかで使ったなーと思ってうろ覚えの知識をあてに色々探したんですが、結局情報を得るのに小一時間かかりました。

調べたことは必ずどこかにメモった方がいいですね。。。

WSLでNGS解析の記事リスト(2020/10/07追記)

wet-to-dry.hatenablog.com

*1:京大のこのOfficeアカウントは最強です。Onedrive 1TBに加え、5台分のOfficeライセンスが付いてこの値段ですからね、、、

*2:一応シングルクオーテーションやダブルクオーテーションで囲うという方法も試してみたがうまくいかなかった

実験マウスを管理するための専用フォームを開発する3

概要

以前から「マウス管理システム」なるものをちょくちょく作っています。

wet-to-dry.hatenablog.com

wet-to-dry.hatenablog.com

これに、いくつかの機能を追加しました。

変更点としては、

  • cssjavascriptのファイルを別ファイルで作成し、読み込ませた

  • spreadsheetへの書き込みを、doPost関数ではなく、「html→javascript→gas」ルートであらかじめ作成した関数を通して書き込みにした

書き込みをdoPostでなく他の関数にしたのは、理由があります。

officeforest.org

このサイトにちょこっと書いてあるのですが、doPost関数は

1プロジェクトで1個しか用意できない

らしいのです。

僕は将来的に、もう少し複雑なアプリを作りたいと思っている(できればデータの追加&削除&シート間の移動などがしたい)ので、1個しか関数を作れないのはとても不便だと思ってました。

なので、doPost関数にとらわれずに、新しく自分で関数を作ることにしました。

できたもの

以下のサイトを参考にしました。

qiita.com

  • Javascriptによるspreadsheetへの書き込み

www.pre-practice.net

スプレッドシートは引き続き以下のものを使用している(URL共有済み)

docs.google.com

コードもいっそ共有してしまおう!

script.google.com

一応コードを下に書きます

main.js

var id = "1HuaAdg-xdo6n_JJXCYgyzD8bAHjl09ngtJbVwF8SXNw";

function doGet(e) {
    // htmlからhtmlへの遷移用。"https://surleconomiejp.blogspot.com/2017/02/google-apps-script-htmlhtml.html"を参考にした。
    Logger.log( Utilities.jsonStringify(e) );
    if (!e.parameter.page) {
        return HtmlService.createTemplateFromFile('index').evaluate();
    }
    return HtmlService.createTemplateFromFile(e.parameter['page']).evaluate();
}

function getScriptUrl() {
    // htmlからhtmlへの遷移用。"https://surleconomiejp.blogspot.com/2017/02/google-apps-script-htmlhtml.html"を参考にした。
    var url = ScriptApp.getService().getUrl();
    return url;
}

function include(filename) {
  // cssやjavascriptの外部ファイルを読み込むための関数。"https://qiita.com/taromorimotohf/items/5e52cb9062600e8ccac3"を参考にした。
  return HtmlService.createHtmlOutputFromFile(filename).getContent();
}

function input_to_sheet_gs(sheetname, value) {
  // spreadsheetにhtmlから直接書き込むための関数。"https://www.pre-practice.net/2017/10/web.html"を参考にした。
  
  // 日時をYYYY//MM//DDの形式に変更
  var dt = new Date();
  var y = dt.getFullYear();
  var m = ("00" + (dt.getMonth() + 1)).slice(-2);
  var d = ("00" + dt.getDate()).slice(-2);
  var time = y + "/" + m + "/" + d;
  
  var ss = SpreadsheetApp.openById(id)
  var sh = ss.getSheetByName(sheetname);
  
  var lastRow = sh.getLastRow() + 1;
  sh.getRange(lastRow, 1, 1, 2).setValues([[value, time]]);
  sh.getRange(lastRow, 3).setFormulaR1C1("=ROUNDDOWN((TODAY()-R" + lastRow + "C2)/7)");
}

index.html

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <base target="_top" />
    <?!= include('css'); ?>
    <?var url = getScriptUrl();?>
  </head>
  <body>
    <h1>マウス管理フォーム</h1>
    オスの匹数
    <select id="male">
      <option value="0">0</option>
      <option value="1">1</option>
      <option value="2">2</option>
      <option value="3">3</option>
      <option value="4">4</option>
      <option value="5">5</option>
      <option value="6">6</option>
      <option value="7">7</option>
      <option value="8">8</option>
      <option value="9">9</option>
      <option value="10">10</option>
    </select>
    <br />
    メスの匹数
    <select id="female">
      <option value="0">0</option>
      <option value="1">1</option>
      <option value="2">2</option>
      <option value="3">3</option>
      <option value="4">4</option>
      <option value="5">5</option>
      <option value="6">6</option>
      <option value="7">7</option>
      <option value="8">8</option>
      <option value="9">9</option>
      <option value="10">10</option>
    </select>
    <br />

    <button id="submit" onclick = "input_to_sheet();window.top.location.href = '<?!=url?>?page=result';">送信する</button>
    <?!= include('js'); ?>
  </body>
</html>

result.html

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <?!= include('css'); ?>
    <!---index.htmlへの遷移用--->
    <?var url = getScriptUrl();?>
  </head>
  <body>
    送信が完了しました。<br /><br />
    
   <!---別のhtmlへの遷移は"https://surleconomiejp.blogspot.com/2017/02/google-apps-script-htmlhtml.html"を参考にした--->
   <input type="button" value="もう一度回答する" onclick="window.top.location.href = '<?!=url?>?page=index';"/>
    <?!= include('js'); ?>
  </body>
</html>

css.html

<style>
body{
background:#000;
color:#fff;
}
</style>

js.html

<script>
  function input_to_sheet() {
    let list = ["male", "female"];
    let sheetname = ""
    for (let i = 0; i < 2; i++) {
      if (i < 1) {
        sheetname = "オス";
      } else {
        sheetname = "メス";
      }
      let value = document.getElementById(list[i]).value;
      google.script.run.input_to_sheet_gs(sheetname, value);
    }
    alert("スプレッドシートに入力しました!")
  }
</script>

あとがき

GAS難しいっすね。

gsファイルからのreturnをJavascriptのalertで表示しようと思ったらうまくいかなんだ。

また解決策がわかったら書きます。

2020/12/03追記

記事をまとめました。

wet-to-dry.hatenablog.com

研究室のPCにSSH接続する話

概要

研究室の自分のPCに出先(自宅など)からアクセスできれば、ラボにデータサーバーを作れてとても便利なのにな~と思っていたので、トライしてみます。

環境は

  • ラボPC (ノート型、Windows10、サーバー用) ※これはそのうち専用のサーバーPCを作る予定

  • 自宅用PC(ノート型、Windows10、クライアント用)

でやっています。

やったこと

このサイトを参考にして設定しました。

qiita.com

1. sshを入れる

windows10にはデフォルトでSSHサーバーおよびSSHクライアント機能が備わっている(はず)。

SSHクライアントは何もいじらずともすでに機能追加済みだったので、サーバーPC側でSSHサーバーの設定を行う。

Windowsマークの隣の検索バーから「option」と検索し、「オプション機能を追加する」をクリック。

f:id:wet-to-dry:20200319200123p:plain

次に、出てきた画面(設定:オプション機能)で「機能の追加をクリック」。

f:id:wet-to-dry:20200319200547p:plain

最後に、OpenSSHサーバーをインストール

f:id:wet-to-dry:20200319200656p:plain

これで、SSHサーバー側の設定は終了!

2. ポート開放

参考にしたサイトには、管理者権限で22ポートを開放させよと書いてあります。

windowsファイアウォールを確認したところ、OpenSSHサーバーアプリは通ってそうだったのですが、とりあえずおまじないとしてやっておきます。

netsh advfirewall firewall add rule name="sshd" dir=in action=allow protocol=TCP localport=22

3. sshdを起動

サーバー側PCで、管理者権限でWindows PowerShellを起動させ、

Start-Service sshd

でサービス起動

Set-Service sshd -StartupType Automatic

自動起動設定(?)にする

一旦PCを再起動。。。


sshdも再起動しようと思ってRestart-Service sshdと打つと、

Could not load host key: __PROGRAMDATA__\\ssh/ssh_host_rsa_key
...

と出てうまく働かないので、以下のページを参考に直した。

chiyosuke.blogspot.com

githubから、FixHostFilePermissions.ps1をダウンロードし、PowerShellで実行

→結構うまくいってそうだった。とりあえずsshd打った時に出てきた

Could not load host key: __PROGRAMDATA__\\ssh/ssh_host_rsa_key
...

とかはなくなった。

4. 接続

ここまで来て、確認のためサーバーPCのWindows PowerShellから

ssh ユーザー名@サーバーIP

と打つと(サーバーIPはネットワークと共有センターなどから調べられるIPv4アドレスってやつ)

The authenticity of host '---.--.--.-- (---.--.--.--)' can't be established.
ECDSA key fingerprint is ---------------------------------------------------------------.
Are you sure you want to continue connecting (yes/no)?

と聞かれるので、yesと答える

すると、

ユーザー名@サーバーIP's password:

と聞かれるので、PCのパスワードを入れる。

すると、いい感じでSSH接続されることがわかる

Microsoft Windows [Version 10.0.18363.720]
(c) 2019 Microsoft Corporation. All rights reserved.

ユーザー名@PC名 C:\Users\ユーザー名>

ただ、ここで何かしらのコードを打つと文字化けしてしまう、、、

文字化けは原因がわからなかったので、いったん置いておく。

また、PowerShellのコードを打つとエラーになる

以下の記事のように、デフォルトではPowerShellではなくコマンドプロンプトが起動するらしいので、PowerShellに変更する。

www.server-world.info

PowerShellを管理者として実行し、

# powershell コマンドの PATH 確認
Get-Command powershell | Format-Table -AutoSize -Wrap

CommandType Name           Version      Source
----------- ----           -------      ------
Application powershell.exe 10.0.18362.1 C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe

# OpenSSH のレジストリーエントリーに DefaultShell=PowerShell を設定
# PowerShell の PATH は上で確認した PATH を指定する
PS C:\Users\Administrator> New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -PropertyType String -Force

DefaultShell : C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
PSPath       : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\OpenSSH
PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE
PSChildName  : OpenSSH
PSDrive      : HKLM
PSProvider   : Microsoft.PowerShell.Core\Registry

以上記事からのコピペを実行した結果

これで、ssh接続した際にPowerShellコマンドを打つことができるようになった。

2020/03/23 追記

この後一応、京大のlocalネットにつないだクライアントPCからはssh接続できました!

あとがき

今日はここまで! また会いましょう!