Raycastを使用したシェルスクリプトの実行（macOS向け）

## はじめに

最近、Linuxのサーバーを扱う機会が増えてきたんですが、Linuxのコマンドラインに慣れておらず、しっかり学ぶことにしました。

まだ熟練してはいませんが、あるタスクを楽にするスクリプトをいくつか作成しました。特にRaycastと組み合わせることで、キーボードショートカットを使用してスクリプトを実行すると、いくつかのワークフローが格段に楽になりました。

このブログの目的は次のとおりです：
1. 私の生活を楽にしてくれるスクリプトをいくつか紹介する
2. Raycastで便利に実行する方法を説明する

## 辞書スクリプト

このスクリプトを使用して日本語の単語を調べていますが、[jisho.org](https://jisho.org)は英語から日本語への翻訳も行うので、どちらにも使えます。

```bash
# クリップボードの内容を変数に保存
selectedText=$(pbpaste)

# 変数が空の場合はエラー
if [ -z "$selectedText" ]; then
  echo "クリップボードにテキストがありません。"
  osascript -e 'display notification "クリップボードにテキストがありません" with title "辞書検索失敗"'
  exit 1
fi

# クリップボードの値をURL用にエンコード
encodedText=$(python3 -c "import urllib.parse; print(urllib.parse.quote(input()))" <<< "$selectedText")

# 標準のブラウザでjishoを開く、検索パラメータ付き
open "https://jisho.org/search/${encodedText}"
```

最初は選択したテキストをクリップボードにコピーしてすぐに検索するスクリプトを作成しようとしましたが、現在のスキルでは一歩多かったです。

現在の使用方法は以下の通りです：

1. `⌘ + C` でテキストをコピー (Macデフォルト機能)
2. `⌥ + D` でスクリプトを実行

一つのステップで実行できるようになれば理想ですが、ショートカットは近いため、現状ではこれで十分便利です。

次のスクリプトに進む前、Raycastで `⌥ + D` を設定する方法をお見せしましょう。

## Raycastでのスクリプトコマンド

Raycastを既に使用していると仮定します。そうでない場合は、私のスクリプトを試すためにインストールしてみてはいかがでしょうか？ Raycastはあなたの仕事をもっと楽にするかもしれません。また、ブログの最後でスクリプトを実行する別の方法を提供します。

Raycastがスクリプトを読み込む専用フォルダを作成しましょう。これにより、最初のスクリプトを追加した後にさらにスクリプトを追加することが簡単になります。ホームでフォルダを作成します。

```bash
# 最初にフォルダを作成
$ mkdir ~/scripts
# スクリプトの編集を開始
$ nano ~/scripts/jisho.sh
```

jisho.shを編集しているときに、スクリプトをコピーして貼り付けます。以下でRaycastに少し追加する必要があります。（nanoを閉じるには：`^ + o` → `↵` → `^ + x`）

```bash
#!/bin/bash

# 必須パラメーター：
# @raycast.schemaVersion 1
# @raycast.title Jisho
# @raycast.mode Compact

# オプションパラメーター：
# @raycast.icon 🤖

# ドキュメント：
# @raycast.description 選択したテキストで辞書検索
# @raycast.author Cas

selectedText=$(pbpaste)

if [ -z "$selectedText" ]; then
  echo "クリップボードにテキストがありません。"
  osascript -e 'display notification "クリップボードにテキストがありません" with title "辞書検索失敗"'
  exit 1
fi

encodedText=$(python3 -c "import urllib.parse; print(urllib.parse.quote(input()))" <<< "$selectedText")

open "https://jisho.org/search/${encodedText}"
```

スクリプトを保存した後、Raycastを開き、`General`または`Raycast settings`を検索して開きます。それから`Extensions` → `Script Commands`に進みます。

![raycast.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3588855/9815d865-f8d2-f044-a58a-e3e23d119f04.png)

`Add Directories`ボタンをクリックして、スクリプトディレクトリを追加します。最後に、Raycastを開き直して「Reload Script Directories」と入力し、そのコマンドを実行します。

これで、`Extensions`タブに戻り、スクリプトのホットキーを追加できます。試してみると動作するはずです！

## 日報スクリプト

毎日仕事後、日報をSlackに投稿します。内容はほぼ毎日同じフォーマットで、以下を含みます：

1. 今日やったこと
2. 次にやること

内容は日によってちょっとだけ変わるので、常に前日の報告書を基にして時間を節約します。しかし、まだ多くのステップが関わっています。

1. 報告書ディレクトリを開く
2. ~/reports/year/month/で昨日の報告書を見つける
3. 報告書を開く
4. その内容をコピーする
5. 今日の報告書を作成し、ファイル名として今日の日番号を付ける
6. そのファイルを開いて、昨日の内容を貼り付ける

一日の終わりにはただ家に帰りたいものです。だから、これをすべて一つのショートカットで実行して自動化しましょう。

```bash
$ nano ~/scripts/daily-report.sh
```

以下のスクリプトをコピーして貼り付けます（nanoを閉じるには：`^ + o` → `↵` → `^ + x`）

```bash
#!/bin/bash

# 必須パラメータ:
# @raycast.schemaVersion 1
# @raycast.title slack-report
# @raycast.mode compact

# オプションパラメータ:
# @raycast.icon 🤖

# ドキュメント:
# @raycast.description 前日の報告から日報を作成
# @raycast.author Cas

# これがあなたの報告書を保存している場所に設定します
base_dir=~/daily-slack-reports

# これをあなたのローカルタイムゾーンに設定します
year=$(TZ="Asia/Tokyo" date "+%Y")
month=$(TZ="Asia/Tokyo" date "+%m")
day=$(TZ="Asia/Tokyo" date "+%d")

echo $year   # 2024
echo $month  # 07
echo $day    # 16

year_dir="$base_dir/$year" 
month_dir="$year_dir/$month"
mkdir -p "$month_dir" # /year/month が存在しない場合に作成します

today_file="$month_dir/$day.md"

# この月のすべてのマークダウンファイルを取得し、パスを削除して最新の日付を選択します
latest_file=$(ls -v $month_dir/*.md 2>/dev/null | grep -E '[0-9]+\.md$' | tail -n 1)

# 月が新しく作成された場合、先月の最新の報告内容からコピーします
# 端のケースは機能させるのが一番難しいことが多いです…
if [ -z "$latest_file" ]; then
    prev_month=$((month - 1))
    month_year=$year
    if [ "$prev_month" -lt 1 ]; then
        prev_month=12
        month_year=$(($year - 1))
    fi
    previous_month_dir="$base_dir/$month_year/$prev_month"
    latest_file=$(ls -v $previous_month_dir/*.md 2>/dev/null | tail -n 1)
fi

# 最新のファイルが見つかった場合、今日のファイルにコピーします
if [ -n "$latest_file" ]; then
    cp "$latest_file" "$today_file"
    echo "Contents copied from $latest_file to $today_file"
fi

# ディレクトリ（コードエディタ内）を開き、その中の今日のファイルを開きます
code -n -r "$base_dir" 
code -r "$today_file"
```

最後の部分では、エディタの`code`コマンドが設定されていることを前提としています。編集が必要な場合はそれに応じて行ってください。

VS Codeの設定方法ですが、VS Codeを開いて `⇧ + ⌘ + P`を押し、`Shell Command: Install 'code' command in PATH`をタイプして実行します。これで動作するはずです！

## Raycastを使わずに実行する方法は？

もちろん、Raycastもおすすめですが、スクリプトをエイリアス経由で実行する方法もあります：

```bash
$ echo 'alias daily-report="~/scripts/daily-report.sh"' >> ~/.zshrc
$ echo 'alias daily-report="~/scripts/daily-report.sh"' >> ~/.bashrc
$ source ~/.zshrc
$ source ~/.bashrc
```

これで、次のようにして実行できます：

```bash
$ daily-report
```

## まとめ

もしかしたら、最新の報告を正しいSlackチャネルにWebhook経由で投稿するスクリプトを作成するのも一つの方法かもしれませんね。

アイディアを出すことが、より良い生産性への道のりの半分を占めるかもしれません。このブログを通じて、そんなアイディアが皆さんの中で芽生える手助けができれば幸いです。このブログを読んで何かスクリプトを作成された方、または役立つと思われるスクリプトのアイデアがあれば、ぜひ共有してください。
```