フォルダ自体を残したまま再利用可能な出力フォルダを空にするには、その中身だけを削除するMacショートカットを作成します。この手順では、固定したフォルダ、使い捨てのテキストファイル、フォルダを確認してから空にするシェルスクリプトを使用します。

この作業では、生成したファイルのバッチごとに1つのフォルダをリセットします。この例には、通常のファイル、名前に空白を含むファイル、隠しファイル、入れ子のフォルダが含まれます。スクリプトはこれらの中身を直接削除し、ゴミ箱には移動しません。Appleが公開している rm マニュアルには、再帰的な削除とエラー報告について記載されています。Appleの rm マニュアル

空にした後に残すものを決める

このワークフローで想定する結果は、同じパスに空のフォルダが残ることです。その中にあるサブフォルダも出力物なので、中身とともに削除されます。出力ディレクトリにテンプレートや恒久的なサブフォルダ構成がある場合は、このスクリプトを使う前に、対象を選ぶルールを変更する必要があります。

例では、ホームフォルダ直下にある Shortcut Output Demo を対象にします。対象を固定しておけば、ショートカットの動作を確認しやすくなります。Finderで開いているウインドウや、たまたま選択されているファイルによって動作が変わることはありません。

要件 この手順での動作
出力フォルダを残す 子パスだけを rm に渡す
隠し出力を含める Bashの dotglob オプションで、ドットから始まる名前も含める
すでに空のフォルダを処理する 子のリストが空でも受け付ける
存在しないフォルダを処理する エラーで停止し、フォルダを再作成しない
入れ子の出力を削除する 各子フォルダを中身ごと再帰的に削除する
Finderの「戻す」を使えるようにする 代わりに以下のFinderを使う方法を利用する

項目をゴミ箱に残したい場合は、Finderを使う方法が便利です。出力フォルダを開き、中にある不要な項目を選択して Command-Delete を押します。親フォルダは選択しないでください。Appleの説明によると、ゴミ箱に移動した項目はゴミ箱を空にするまでそこに残り、ファイル > 戻す で復元できます。Macでファイルやフォルダを削除する

初回実行用の使い捨てフォルダを作る

ターミナルを開き、以下のセットアップブロック全体を貼り付けます。作成されるのはテスト用のテキストファイルのみです。ファイルを書き込む前に、最初の mkdir が成功する必要があります。そのため、Shortcut Output Demo という名前のファイルやフォルダがすでにある場合、セットアップはその中身を再利用せずに停止します。

/bin/bash <<'BASH'
set -eu
target="$HOME/Shortcut Output Demo"

if ! /bin/mkdir "$target"; then
  printf 'Setup stopped: choose an unused demo folder name.\n' >&2
  exit 1
fi

/bin/mkdir "$target/Batch"
printf 'Synthetic output A\n' > "$target/alpha.txt"
printf 'Synthetic output B\n' > "$target/sample output.txt"
printf 'Synthetic marker\n' > "$target/.demo-marker"
printf 'Synthetic nested output\n' > "$target/Batch/nested.txt"
printf 'Created disposable examples in: %s\n' "$target"
BASH

Finderでホームフォルダを開き、Shortcut Output Demo を探します。中には、alpha.txt、sample output.txt、Batch の3つの表示項目があります。4つ目の項目 .demo-marker は意図的に隠されています。Batch の中には nested.txt があります。これらは例として用意したテスト入力であり、既存のユーザーファイルではありません。

同じ名前がすでに存在するためセットアップが停止した場合は、その項目には手を加えないでください。まだ使われていない別のデモ名を選び、セットアップと削除スクリプトの両方で対象の代入値を変更して、一致させます。名前の重複を回避するために、最初の作成チェックを削除しないでください。

ショートカットを作り、入力と出力の種類を保つ

「ショートカット」アプリで追加ボタンをクリックしてショートカットを作成し、名前を Clear Demo Output にします。アクションリストで Run Shell Script を検索して追加します。Appleの説明では、アクションを追加してショートカットを作成する方法や、名前でアクションリストを検索する方法が紹介されています。Macでカスタムショートカットを作成する、Macの「ショートカット」でアクションリストを操作する

アクションの Shell を /bin/bash に設定し、サンプルコマンドを以下の削除スクリプト全体に置き換えます。このスクリプトではBashの配列と shopt を使うため、このシェル設定を維持してください。対象はスクリプト内の代入値から読み取ります。ショートカットの入力、標準入力、コマンドライン引数は使用しません。

スクリプトが無効になっている場合は、ショートカット > 設定 を選び、詳細 を開いて スクリプトの実行を許可 を有効にします。Appleの説明では、ショートカットからスクリプトを実行するための設定として案内されています。Appleのスクリプト実行設定

set -u
target="$HOME/Shortcut Output Demo"

if [[ ! -d "$target" || -L "$target" ]]; then
  printf 'Expected an existing ordinary folder: %s\n' "$target" >&2
  exit 1
fi

if [[ ! -r "$target" || ! -x "$target" ]]; then
  printf 'Cannot list the output folder.\n' >&2
  exit 1
fi

unset GLOBIGNORE
set +f
shopt -u failglob
shopt -s dotglob nullglob

items=( "$target"/* )
for item in "${items[@]}"; do
  if ! /bin/rm -R -- "$item"; then
    printf 'Clearing stopped; some items may remain.\n' >&2
    exit 1
  fi
done

remaining=( "$target"/* )
if (( ${#remaining[@]} != 0 )); then
  printf 'The folder still contains items.\n' >&2
  exit 1
fi

printf 'Folder is empty: %s\n' "$target"

アクションが成功すると、Folder is empty: で始まるテキストが出力されます。これはフォルダオブジェクトでも、削除したファイルのリストでも、再利用可能なディレクトリへの参照でもありません。後でショートカットを拡張する場合、フォルダを必要とするアクションには出力先フォルダを明示的に渡してください。Appleのアクション情報パネルには、受け付ける入力と生成される出力が表示されます。アクションのアイコンをControlキーを押しながらクリックし、「情報を表示」を選ぶと確認できます。アクションの入力と出力に関する情報を表示する

完了を画面で知らせるには、スクリプトの後に Show Alert を追加し、メッセージにスクリプトの出力変数を挿入します。Appleの説明では、前のアクションの出力を Show Alert に渡して確認する方法が紹介されています。フォルダが空だと固定メッセージで知らせるより、スクリプトの実際の結果を表示するほうが有用です。Macのショートカットで「Show Alert」アクションを使う

フォルダが残る理由を確認する

items=( "$target"/* ) の代入では、子パスを収集します。ループは各子を個別に rm に渡し、\"$target\" 自体を渡すことはありません。そのため、再帰的な削除は出力用サブフォルダに適用され、再利用可能な親フォルダは残ります。

よくあるリセット時の問題には、2つのBashオプションで対応します。dotglob はドットから始まるファイル名を含め、nullglob は一致するパターンがない場合に何も展開しないようにします。配列を引用符で囲んで展開することで、空白を含むファイル名も個別の引数として保持できます。これらの動作は、Appleが配布するBashマニュアルに記載されています。Bashマニュアル:パス名展開と配列

削除コマンドは入れ子のフォルダに -R を使い、オプションの解析を終了するために -- を使います。各コマンドの結果を確認し、失敗した場合は停止します。Appleの rm マニュアルによると、エラーが発生すると終了ステータスは0以外になります。削除は一括処理ではありません。後の子の削除に失敗しても、すでに削除した子は復元されません。Appleの rm マニュアル

このスクリプトは、対象がシンボリックリンクの場合も拒否します。この例は、マウントされたボリュームを含まない通常のローカル出力フォルダを対象にしています。削除する前に、出力を生成しているプロセスを停止してください。実行中または実行後にファイルが作られると、フォルダが空のままという想定が崩れる可能性があります。

初回実行と繰り返し実行を確認する

エディタの実行ボタンを使ってショートカットを実行します。対象パスを変更する前に、以下の手順どおりに結果を確認してください。Appleの説明では、エディタからカスタムショートカットをテストする方法が紹介されています。カスタムショートカットをテストする

  1. Finderで Shortcut Output Demo がまだ存在することを確認します。
  2. 表示されていたサンプルファイルと Batch フォルダが消えていることを確認します。
  3. スクリプトが空フォルダのメッセージを返したことを確認します。最終チェックでは隠し項目も確認されます。
  4. ショートカットをもう一度実行します。すでに空のフォルダでも同じメッセージが表示されるはずです。
  5. 空のデモフォルダの名前を一時的に変更してから、もう一度実行します。スクリプトはフォルダが存在するというエラーで停止するはずです。その後、元の名前に戻します。

削除スクリプトは bash -n によるBash構文チェックに合格しています。この記事ではmacOSの「ショートカット」アプリ上で実行していないため、初回実行前に使い捨てのフォルダを用意する手順を含めています。

削除に失敗した場合は、再試行する前に報告された項目とフォルダ内に残っているものを確認してください。対象がない場合、ディレクトリを読み取れない場合、削除に失敗した場合は、それぞれ異なる状態です。スクリプトはそれらを成功メッセージに置き換えません。

衝突時の処理を決めつけずにフォルダを再利用する

使い捨てのテストが想定どおりに動いたら、対象の代入値を選んだ出力フォルダに変更します。まず中身を確認し、隠し項目やサブフォルダも含めて、すべて置き換え可能な出力物であるという前提を守ってください。

フォルダを空にすると、その時点で存在する名前が削除されます。後続の書き出しや保存アクションで、2つの新しい出力の名前が同じ場合にどうなるかは定義しません。置き換え、統合、自動での名前変更が行われると決めつけず、アクション独自のオプションや説明を確認してください。Appleは Show Info からアクションの説明を確認できるようにしています。アクションの動作を確認する

保存したショートカットは、以下のコマンド全体を使ってターミナルから実行することもできます。Appleの説明では、空白を含むショートカット名を引用符で囲む方法と、shortcuts コマンドは成功すると 0 を返し、エラー時は 1 を返すことが案内されています。コマンドラインからショートカットを実行する

shortcuts run "Clear Demo Output"

前のバッチの処理を終え、選んだフォルダを空にして、結果を確認してから次のバッチを作成するという順序で、意図的に出力を削除・生成してください。これにより、再利用可能なフォルダの役割が明確になり、繰り返し実行しても予測しやすくなります。

出典