VSCode のタスク機能 + WSL2 でシェルスクリプト自動化

# やりたいこと
VSCode のタスク機能と WSL2 を使って、シェルスクリプトを自動起動させる
## メリット
- VSCode のキーボードショートカットだけで、シェルスクリプトの自動化が可能
- VSCode で作業フォルダ（プロジェクト）を開いただけで、シェルスクリプトの自動化が可能

では始めましょう。
# 作業の流れ
**検証環境は Windows10 WSL2(Ubuntu-22.04)**
- 作業フォルダ(プロジェクト)と準備
- tasks.json の作成
- VSCode のキーボードショートカットでタスク自動化
- VSCode で作業フォルダを開くだけでタスク自動化
- その他
# 作業フォルダ(プロジェクト)作成と準備
簡単なサンプルで説明します。サイトに毎日アップする日記の下書きのようなものを想定しています。
まずは、VSCode を起動させてください。WSL2 をリモート接続して、以下のようにホームディレクトリ直下に作業フォルダ `Diary` を作ります。
`/home/<ユーザー名>/Diary/`
（ちなみに、WSL のリモート接続には、「WSL」という名の拡張機能が必要です）  
WSL の Windows側のホームディレクトリで作業フォルダを作ることもできますが、WSL の Linux側で作るほうがパフォーマンスがよいです。
注意、必ず VSCode で作業フォルダを開いて中に入っている状態にしてください。  
シェルスクリプトは以下のコードです。
diary.sh
```
#!/bin/bash
current_date=$(date '+%F')
echo $current_date > $current_date.txt
```
シェルスクリプトの内容は、タスクを実行した日の日付がファイル名になったテキストファイルが作成されます。そして作成されたファイルの一行目にその日付が書き込まれるというものです。
例えば、タスクを実行すると、**2023-11-20.txt** というファイルが作成されて、そのファイルの一行目に**2023-11-20**と書き込まれます。
# tasks.json の作成
VSCode でタスクを実行するには、**tasks.json** を作成する必要があります。
その前にちょっとタスクについて説明します。
VScode のタスク機能には二種類のタスクがあります。
ユーザータスクは、どの作業フォルダ（プロジェクト）からもタスクの実行が可能なグローバルなタスク。
一方、カスタムタスクは、その作業フォルダでのみタスクの実行が可能なタスクです。タスクを実行するには、tasks.json を次のようなフォルダ構成で作っておく必要があります。
`~/Diary/.vscode/tasks.json`
今回は、**カスタムタスク**のほうの tasks.json を作成したいと思います。
（メリットはタスクの変更や削除が手元にあるので楽ちん）
では早速、tasks.json を作ってみましょう。
1. VSCode で 作業フォルダ（Diary）を開いている状態で、コマンドパレット（Ctrl + Shift + P）を開いて、「task」と入力
1. 「タスクの構成...」を選択
1. 「テンプレートから tasks.json を作成」を選択
1. 「Others」を選択

以下のような tasks.json ができていれば成功です。
（ちなみにユーザータスクのほうを作成したい場合は、2.「タスクの構成...」の代わりに「タスク:ユーザータスクを開く」を選択すればいいです。あとは同じです）
~/Diary/.vscode/tasks.json
```
{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "tasks": [
        {
            "label": "echo",
            "type": "shell",
            "command": "echo Hello"
        }
    ]
}
```
シェルスクリプトの場合は、以下のように書き換えます
```
  "tasks": [
    {
      "label": "diary_date",
      "group": "none",
      "type": "process",
      "command": "./diary.sh",
    }
  ]
```
プロパティの "label" はタスクの名前です。日本語でもオッケーです。
"group" はタスクのグループ名で、"none" はビルドとかではなく通常のタスクという意味です。
"type" は、"shell" と "process" があって、テンプレートのようにコマンドが echo のような通常のシェルコマンドの場合は、"shell"、`.bat` や `.sh` などの場合は、"process" です。
注意点は、"shell" の場合、コマンドを `"echo Hello"` のように、コマンドと引数をまとめて書くことができますが、"process" の場合、引数があるときは、"args" を使って、以下のように配列形式で書く必要があります。
`"args": ["引数1","引数2"]`
## タスクの実行
ではタスクを実行してみましょう。
1. コマンドパレット（Ctrl + Shift + P）を開く
1. 「タスクの実行...」を選択
1. 実行したいタスク（diary_date）を選択

（最初の一回だけ次の画面が表示されるので「タスクの出力をスキャンせずに続行」を選択）
今日の日付が一行目に入ったテキストファイルが自動作成されれば成功です。
# VSCode のキーボードショートカットでタスク自動化
作成したタスクを keybinding.json に登録すれば、簡単なキー入力でタスクを実行することができるようになります。
keybinding.json の表示
1. VSCode 画面左下の設定ボタンをクリック
1. 「キーボードショートカット」を選択
1. VSCode 画面右上の三つ並んだボタンの一番左のボタンをクリック

![qiita.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1958320/c7de20f2-b0f9-dfa9-18f1-4775786fbe39.png)
keybinding.json に以下のコードを追加してください。
keybinding.json
```
{
    "key": "alt+z",
    "command": "workbench.action.tasks.runTask",
    "args":"diary_date",
}
```
"args" の値には、実行したいタスク名（"label"に記述した値）を書いてください。
これで「Alt + Z」のキー入力でタスクを実行できるようになります。
（ショートカットキーの重複には注意）
先ほど作成したテキストファイルを削除して、ぜひ試してみてください。
# VSCode で作業フォルダを開くだけでタスク自動化
簡単です。以下のようにオプション加えるだけです。
tasks.json
```
  "tasks": [
    {
      "label": "diary_date",
      "group": "none",
      "type": "process",
      "command": "./diary.sh",
      "runOptions": {
        "runOn": "folderOpen"
      }
    }
  ]
```
これで作業フォルダ（Diary）を開くだけで、今日の日付入りのテキストファイルができるようになります。一度作業フォルダを閉じてから、再度開き直してみてください。
# その他
タスクを実行すると、新しいターミナルを開いて、その実行結果を出力してくれます。
こちらも見た目や表示方法などをオプションと値を指定することで変更することができます。私個人の好みでは、以下のように設定しています。
```
  "tasks": [
    {
      "label": "diary_date",
      "group": "none",
      "type": "process",
      "command": "./diary.sh",
      "presentation": {
        "reveal": "silent"
      }
    }
  ]
```
`"reveal": "silent"` とすると、問題が検知されたときだけ表示されるようになります。
パネルは隠れているだけで、ターミナルの右側のチェックマークボタンをクリックすると、アクティブになってちゃんと表示されます。必要な時だけアクティブにしたい方はぜひ。

それから最後に、上記では WSL のLinux側のホームディレクトリに作業フォルダを作成しましたが、Windows側のホームディレクトリに作業フォルダを作る場合の例も記述しておこうと思います。
```
  "tasks": [
    {
      "label": "diary_date",
      "group": "none",
      "type": "process",
      "command": "C:\\Windows\\System32\\wsl.exe",
      "args": [
        "-d",
        "Ubuntu-22.04",
        "/mnt/c/Users/<PCユーザ名>/Diary/diary.sh"
      ]
    }
  ]
```
作業フォルダ（Diary）を `C:\Users\<PCユーザ名>\` 直下に置いた例です。
前述したとおり "process" のコマンドの引数は、"args"オプションを使います。
パスはフルパスです。
また、作業フォルダは Windows側のホームディレクトリに作っておき、シェルスクリプトのファイルだけ WSL の Linux側に置いた場合の例は、次のようになります。
```
  "tasks": [
    {
      "label": "diary_date",
      "group": "none",
      "type": "process",
      "command": "C:\\Windows\\System32\\wsl.exe",
      "args": [
        "-d",
        "Ubuntu-22.04",
        "/home/<Ubuntuユーザ名>/Diary/diary.sh"
      ]
    }
  ]
```
パフォーマンスは落ちますが、それでもいいや、という方はぜひ。
以上、長くなりましたが、参考にしていただければ幸いです。