【はじめてのBash】エンジニアが書いているBashコマンドってなに書いてあるん？

業務の中でbashコマンドに触れることが度々あったので多少読めるようにならないとな…
と思い勉強することにしました。

基本的な記述を読めるぐらいのレベルを目指したいと思います！

:::note info
【この記事をオススメしたい方】
・Bashってなに？ってぐらい初学者
・業務で時折見るので読めるようになりたい方
:::

## Bashってなに？
wikiには下記のように記載がありました。

> Bash(バッシュ)はUnixシェルかつコマンド言語（英語版）であり、GNUプロジェクトにおけるBourne Shellのフリーソフトウェアによる代替としてブライアン・フォックス（英語版）によって作成された。Bashは1989年に初めてリリースされ、ほとんどのLinuxディストリビューションのデフォルトのログインシェルとして広く普及している。Windows 10におけるWindows Subsystem for Linuxでも利用可能である。

https://ja.wikipedia.org/wiki/Bash

:::note info
お手軽にBashコマンドを試したいという方はオンラインでも試せるものがあったので利用ください！
:::

https://paiza.io/projects/6vv-RLGH0atPVBC-cK7DCQ?language=bash

## Bashでシェルスクリプトの作成
Bashで記述するファイルの拡張子は「.sh」となります。

Bashで書かれてシェルスクリプトであることを伝えるためにファイルの先頭に`#!/usr/bin/bash`と記載するようです。

`exit 0`はbashの終了を意味しています。

```sample.sh
#!/usr/bin/bash

echo "hoge"

exit 0
```

Bashの実行はコマンドラインで`bash sample.sh`で実行できます。
`#`はコメントアウトとなり、複数行のコメントアウトをする場合は`<< COMMENTOUTとCOMMENTOUT`で囲みます。

```sample.sh
#!/usr/bin/bash

<< COMMENTOUT
echo "hoge"
echo "hogehoge"
COMMENTOUT

exit 0
```

:::note alert
【コメントで教えていただきました】
こちらのコメントアウトの方法だと変数などが間に入っていた場合展開されてしまうそうです…。
なので複数コメントアウトしたい場合は`COMMENTOUT　(デリミタ:区切り文字）`の部分を引用符で囲むと良いそうです。

```sample.sh
<< "COMMENT"
echo "hoge"
echo "hogehoge"
COMMENTOUT
```

さらに詳細を知りたい場合は参考記事をご覧ください！
:::


### 変数の定義

```sample.sh
#!/usr/bin/bash

number=3 
string="hogehoge"

echo ${nunmber}
echo ${string}

exit 0
```

変数は`${変数名}`で出力することができます。

:::note alert
「=」の前後に空白を入れるとエラーになるので注意
:::

### 文字列の操作
文字数は変数名の頭に`#`をつけることで求めらるらしい…便利。
文字の切り出しは1文字目を0として`変数名：開始位置：終了位置`で指定すると切り出すことができます。

```sample.sh
#!/usr/bin/bash

string="hogehoge"

echo ${#string}
# 出力される値：8

echo ${string:0:3}
# 切り出される文字：hog

exit 0
```

文字列の置換は一致したものを全て置換したい時は`//`一番はじめに一致したものだけを置換したいときは`/`を使います。

```sample.sh
#!/usr/bin/bash

string="hogehoge"

echo ${string//h/f}
# 出力される文字：fogefoge

echo ${string/h/f}
# 切り出される文字：fogehoge

exit 0
```

## 配列操作
配列の操作はJavaScriptとそれほど大差ないと感じました。
「＠」を指定すると全部出力されるのは便利です…

```sample.sh
#!/usr/bin/bash

# 配列の定義
array=("hoge1" "hoge2" "hoge3" "hoge4")
echo ${array[0]}
# 出力される文字：hoge1

# 全部出力
echo ${array[@]}
# 出力される文字：hoge1 hoge2 hoge3 hoge4

# 出力する区間を指定する
echo ${array[@]:1:2}
# 出力される文字：hoge2 hoge3

# ◯番目以降を指定する
echo ${array[@]:2}
# 出力される文字：hoge3 hoge4

# 最後を出力
echo ${array[${#array[@]}-1]}
# 出力される文字：hoge4

exit 0
```

## ループ
forで書ループ分もそんなに変わりなさそう。
個人的には「{}」でブロックにするのが馴染みあるので少し違和感ですが…。

```sample.sh
#!/usr/bin/bash

# 配列の定義
array=("hoge1" "hoge2" "hoge3" "hoge4")

for (( i = 0; i < ${#array[@]}; ++i ))
do
    echo ${array[$i]}
done

exit 0
```

forの中の各種値をカッコで囲まないとエラーになりましたのでこれは必要そうです。
※カッコで囲む理由はわかりません。

```sample.sh
# ここのカッコのことです
( i = 0; i < ${#array[@]}; ++i )
```

:::note info
【コメントで教えていただきました】
こちらのカッコは構文の1つで「double parentheses」というもので算術展開と評価をすることができるそうです！
中身が「0」の場合は偽値となるようです。
:::

## if文
書き方に少し違和感はあるものの大体一緒。

```sample.sh
#!/usr/bin/bash

string="hoge"
string2="hoge"

# 文字列の比較
if [ "$string" = "$string2" ]; then
  echo "true"
else
  echo "false"
fi

# elseを省略することも可能
if [ "$string" = "$string2" ]; then
  echo "true"
fi

exit 0
```

:::note warn
下記のように「]」の前にスペースがないとエラーになります。
少しインデントを間違えるだけでエラーになってしまうので構文はもちろんですが、インデントやスペーシングにも注意が必要です。
```sample.sh
if [ "$string" = "$string2"]; then
```
数値を比較する場合は数値比較演算子というものがあるらしく記号のようなものを使うみたいです。
詳しくは参考記事にまとめておきましたのでそちらをご覧ください！
:::

## まとめ
JavaScriptを普段触っているとなんとなく読めますが、中には見慣れない記述もある印象です。
Bashをゴリゴリ書くというより読めるぐらいでいいかなというのが僕のスタンスなのでライトに学びました。

普段使っているRaycastというツールではBashやNode.jsで書いたスクリプトを呼び出すことができるのでBashをカスタムできるのが本当は望ましいですが…フロントエンドの技術という観点ではNode.jsの方が優先度高いかと考えています！

Node.jsもいい加減やります…。

スクリプトのことは記述していませんが、Raycastについては概要をまとめた記事があるので興味ある方はご覧ください！

https://qiita.com/tanimoto-hikari/items/919af226ea262be85941

## 参考記事

### 基本構文について

https://www.sejuku.net/blog/54333

https://bi.biopapyrus.jp/os/linux/bash.html

### 「double parentheses」について

https://qiita.com/Ping/items/f9b5175085026462b082#double-parentheses--

https://tldp.org/LDP/abs/html/dblparens.html

### 数値比較演算子について

https://qiita.com/egawa_kun/items/196cd354c0d8e4e0fefc

### ヒアドキュメントでのコメントアウトについて

https://qiita.com/tak4/items/377b45804c58a3438153