シェルスクリプトを理解する

# はじめに
シェルスクリプトを使用する機会があったので、なんとなく理解しているシェルスクリプトを簡単に記事にまとめて、整理したいと思います。

# シェルスクリプトとは？
シェル（コマンドラインインターフェース）で実行される一連のコマンドをまとめたテキストファイルのことです。シェルスクリプトを使うことで、複雑なタスクを自動化したり、複数のコマンドを連続して実行したりすることができます。
シェルスクリプトは一行ずつ順番に処理され、各コマンドが完了するまで次の行に進むことはありません。

# シェルスクリプト例
```shell: script.sh
#!/bin/bash

# コメント
echo "Hello, World!"  # メッセージを表示

# 変数の定義
name="k96mz"
echo "My name is $name"

# ループ
for i in {1..5}; do
    echo "Number $i"
done
```
ループについては、doでループが開始され、doneがループの終わりを示します。


### 実行結果
![スクリーンショット 2024-10-21 12.09.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3684675/9fc873d5-9577-f1c5-468b-e5554c03c052.png)

### #!/bin/bashとは？
シェルスクリプトの最初の行に記述される「シバン」と呼ばれる特殊な構文です。
/bin は、システムの主要な実行可能ファイルが格納されるディレクトリで、bash はその中の特定のシェルプログラムです。例えば、自身のシェルスクリプト実行環境がZsh（Z Shell）だとしても、「シバン」を利用することで、bash環境で実行出来ます。
もしシバンがない場合は、スクリプトはそのシェルで実行されます。つまり、現在ログイン中のシェルがbashであればbashで、zshであればzshで実行されます。

## unvtで使用されているシェルスクリプト
次は[こちら](https://github.com/unvt/produce-gsc-6/blob/main/work_every.sh)で使用されているシェルスクリプトを見てみます。

```shell: script.sh
node produce-gsc-osm/index_everyday.js
for f in produce-gsc-osm/mbtiles/osm_tile_every/*.mbtiles; do /usr/local/bin/tile-join --no-tile-size-limit -f -o large_tiles/unosm/tile_every/`basename ${f}` produce-gsc-un/mbtiles/un_tile/`basename ${f}` produce-gsc-osm/mbtiles/osm_tile_every/`basename ${f}`; date; echo  `basename ${f}`; ls -alh large_tiles/unosm/tile_every/`basename ${f}` ;done
scp -i XXX(path to your ssh key) -r ./large_tiles/unosm/tile_every/* (username)@(hostingserver):(path)/mbtiles/unosm
```

### 解説
node produce-gsc-osm/index_everyday.js:
index_everyday.js というNode.jsスクリプトを実行します。

for f in produce-gsc-osm/mbtiles/osm_tile_every/*.mbtiles; do ... ; done:
for ループを使って、produce-gsc-osm/mbtiles/osm_tile_every/ ディレクトリ内のすべての .mbtiles ファイルに対して処理を実行します。変数 f には各 .mbtiles ファイルのパスが代入されます。

-o large_tiles/unosm/tile_every/\`basename \\${f}\` ：
出力ファイルのパスを指定しています。\`basename \\${f}\` において、basename は、指定したパスからファイル名の部分だけを取り出すコマンドです。ここでf にはループ内で処理されている .mbtiles ファイルの完全なパスが格納されていますので、もしfが「produce-gsc-osm/mbtiles/osm_tile_every/0-0-0.mbtiles」であれば、basename ${f}は「0-0-0.mbtiles」となります。

date:
現在の日付と時刻を表示します。これにより、処理が行われた時間を確認できます。

echo  \`basename \\${f}\`:
現在処理中のファイル名を表示します。これにより、どのファイルが処理されているのかを確認できます。

ls -alh large_tiles/unosm/tile_every/\`basename \\${f}\`:
結合されたタイルファイルの詳細情報（ファイルサイズ、パーミッション、最終更新日など）をリスト表示します。

### scpコマンドとは？
scp（Secure Copy Protocol）は、リモートコンピュータ間やローカルコンピュータとリモートコンピュータ間でファイルを安全にコピーするためのコマンドです。scpはSSH（Secure Shell）プロトコルを使用して通信を暗号化し、安全にデータを転送することができます。

基本的なscpコマンドの構文
```
scp [オプション] ソースファイル ユーザー名@ホスト名:ターゲットパス
```

```
scp -i XXX -r ./large_tiles/unosm/tile_every/* (username)@(hostingserver):(path)/mbtiles/unosm:
```

上記コードは、scp コマンドを使用して、ローカルの large_tiles/unosm/tile_every/ ディレクトリ内のすべてのファイルをリモートサーバーにコピーします。
• -i XXX は、SSH接続時に使用する秘密鍵のパスを指定します。
• -r は、ディレクトリを再帰的にコピーするオプションです。
• ./large_tiles/unosm/tile_every/* は、コピーする対象のファイルを指定します。
• (username)@(hostingserver):(path)/mbtiles/unosm は、リモートサーバーのユーザー名、ホスト名、およびファイルをコピーするパスを指定しています。


# 実行権限の付与
シェルスクリプトを実行するには実行権限の付与を行う必要があります。以下のように実行します。

```
chmod +x script.sh
```
chmod +x script.sh コマンドは、LinuxやUnix系のオペレーティングシステムにおいて、script.sh というファイルに対して「実行権限」を付与するためのコマンドです。

## unvtで使用されているシェルスクリプト

```
sudo chown -R hoge:hoge produce-gsc-6
```

chown: “change owner”の略で、ファイルやディレクトリの所有者を変更するためのコマンドです。

-R:“recursive”の略で、指定したディレクトリ内のすべてのファイルとサブディレクトリにも適用することを示します。このオプションを指定することで、produce-gsc-6ディレクトリ内のすべてのファイルとフォルダの所有者を変更できます。

hoge:hoge:所有者とグループを指定します。最初のhogeは新しい所有者のユーザー名、コロン（:）の後のhogeは新しいグループ名を示します。この場合、所有者とグループの両方がhogeに設定されます。

```
sudo chmod produce-gsc-6/777 work*.sh
```

777 は、アクセス権限を指定する数値です。この場合、所有者、グループ、その他すべてのユーザーに対して、読み取り（4）、書き込み（2）、実行（1）のすべての権限を与えています。

work*.sh: work で始まり .sh で終わるすべてのファイル名を示します。アスタリスク（*）はワイルドカードで、任意の文字列にマッチします。これにより、例えば work1.sh、work2.sh、work_script.sh などが含まれます。


# まとめ
シェルスクリプトについて整理しました。

# Reference

https://qiita.com/k96mz/items/4effe7ed33c499a1dbd8