Bash 基礎 Part 01 -- 入出力と API リクエスト
Tags: bash
Published: 2022-08-13 16:01:00


## why

運用などで shell script を書くことが多いが
全然文法わからなくて困ったのでまとめる。

---

# 入出力の基礎

---

## $NAME や 'name: ${NAME}' で変数に入れて出す

https://qiita.com/Ping/items/57fd75465dfada76e633#%E5%A4%89%E6%95%B0%E6%96%87%E5%AD%97%E5%88%97

```sh
#!/bin/bash

NAME='kaede'
echo NAME
echo $NAME
```

NAME 変数に kaede の文字列をいれて
NAME と $NAME を出力すると

```php
❯ ./test.sh 
NAME
kaede
```

$ がついていない方は変数として処理されない。
変数の中身を出力する時は $ が必要。

```sh
echo 'Hello ${NAME} !!!'
echo "Hello ${NAME} !!!"
```

> Hello kaede !!!
> Hello ${NAME} !!!

JS のように、変数リテラルで展開して出すこともできる。
シングルクォートだと展開されない。

---

## ${number} や ${@} で引数を扱う

https://qiita.com/Ping/items/57fd75465dfada76e633#%E4%BD%8D%E7%BD%AE%E3%83%91%E3%83%A9%E3%83%A1%E3%83%BC%E3%82%BF

位置パラメータというらしい。

```sh
echo "arg1: ${1} arg2: ${2}" 
```

```php
❯ ./test.sh inputOne inputTwo inputThree
arg1: inputOne arg2: inputTwo
```

引数は $1 ~ $10 で扱える

```sh
echo "  args: ${@}  "  
```

```php
❯ ./test.sh hoge hoge hoge hoge hoge hoge hoge hoge hoge hhhho hoge
  args: hoge hoge hoge hoge hoge hoge hoge hoge hoge hhhho hoge 
```

$@ で全て扱える

---

## ${number-"default"} で引数がない場合のデフォルトを設定する

https://qiita.com/Ping/items/57fd75465dfada76e633#bash%E3%81%AE%E5%A4%89%E6%95%B0%E5%B1%95%E9%96%8B%E6%99%82%E3%81%AE%E7%BD%AE%E6%8F%9B

```sh
echo "arg1: ${1-"NOARG1"}" 
```

```php
❯ ./test.sh    
arg1: NOARG1
❯ ./test.sh hoge  
arg1: hoge
```

ハイフンをつけることで、その値がない場合に
代入される値を書くことができる。

つまり、引数がない場合の動作を書くのに使える。

---

## $(</dev/stdin) で標準入力を扱う

```sh
echo $(</dev/stdin)
```

$(</dev/stdin) でファイルのリダイレクトで渡されたものを扱える。

```php
❯ cat ids.txt 
1000
1001
❯ ./test.sh < ids.txt
1000 1001
```

渡した ids.txt の中身にアクセスできた。

---

## while {index} do {処理} done < fileName.txt で渡したファイルを一行一行処理する

https://stackoverflow.com/a/1521498

```sh
while read id
do
  echo "https://jsonplaceholder.typicode.com/users/$id"
done < "${1:-/dev/stdin}"

```

while read {valueName}
で受け取ったものでループできる

```php
❯ ./test.sh ids.txt 
https://jsonplaceholder.typicode.com/users/1000
https://jsonplaceholder.typicode.com/users/1001
```

これで渡した ids のテキストファイルに応じて
リクエストに組み込む便利スクリプトを作れる。

https://phoenixnap.com/kb/curl-command

curl の使い方はこちら

-v, -XPOST, -s, -S など色々ある

---
---

# 処理の基礎

## if [条件1] then {しょり} elif [条件2] then; 処理 で条件によって分岐実行する

https://www.thegeekstuff.com/2010/06/bash-if-statement-examples/

https://qiita.com/toshihirock/items/461da0f60f975f6acb10

```sh
#!/bin/bash                                       

if [ $1 -eq 100 ];
then
  echo "one hundred"
elif [ $1 -gt 100 ] ; 
then 
  echo "Over one hundred"
elif [ $1 -lt 100 ] ; 
then 
  echo "Under one hundred"
else
  echo "Other value"
fi
```

```php
❯ ./test.sh 100  
one hundred
❯ ./test.sh 101
Over one hundred
❯ ./test.sh 99 
Under one hundred
./test.sh -1.1 
./test.sh: line 3: [: -1.1: integer expression expected
./test.sh: line 6: [: -1.1: integer expression expected
./test.sh: line 9: [: -1.1: integer expression expected
Other value
```

このように、
if [条件] then; で処理を書いて
elif [条件] then; で次の場合の処理 x n
else で最後の処理

と分岐処理が書ける。

100 = 100 が 100 -eq 100
101 > 100 が 100 -gt 100
099 < 100 が 099 -lt 100

と書ける。珍しい書き方！

1 is less than 100 で覚えることにする。

---

# 応用編

## awk で中身を削る

https://www.geeksforgeeks.org/awk-command-unixlinux-examples/

正規表現で中身を削れる。

```php
awk '{print}' ids.txt
1000 sato eng
1001 kato biz
1001 ookubo biz
```

囲った print で普通に cat できて

```php
awk '/to/ {print}' ids.txt 
1000 sato eng
1001 kato biz
```

シングルクォートの内部の前半に regex を持ってくると
正規表現で絞れる。

```php
❯ awk '{print $2}' ids.txt
sato
kato
ookubo
```

$2 で二列目だけ絞れる。 

---

## jq で中身を削る

https://jsonapi.org/examples/

これを json.json として作って

```
jq . json.json
```

jq . でファイルを指定すると綺麗に出力できる。
フォーマットにあっている json じゃないとエラーになる。

```
jq '.data[0].type' json.json
```

名前と配列名で絞り込める。

```sh
valName=${cat hoge.json | jq.data[0].id}
```

${} の中で削れば変数に格納できる。



---

## curl で HTTP リクエストを送る

https://www.keycdn.com/support/popular-curl-examples

基本

https://qiita.com/ryuichi1208/items/e4e1b27ff7d54a66dcd9#%E5%9F%BA%E6%9C%AC%E5%BD%A2

---

### -H でヘッダー情報を送る

オプション情報

https://mkyong.com/spring/curl-post-request-examples/

-H "Content-Type: application/json" 

これでヘッダー情報を body に詰めて送れる。
複数送る時は -H ごと複数追記する。

### -d で (JSON) データを送る

-d '{"key1":"val1","key1":"val"}'

これで json を body に詰めて送れる。

### -v でレスポンスをターミナルに表示する

-v

これで結果が 200 か 500 か 404 かわかる。

### POST の実例

```php
curl -v -X POST -H "Content-Type: application/json" \
-d '{"name":"test", "age":20}' \
http://localhost:8080/persons
```

このように使える。

### DELETE の実例

```php
curl -v -X DELETE https://some-api/1234
> HTTP/1.1 204 No Content
```

このように、成功すると大抵 204 が返ってくる
同じ ID に　GET して 404 が返ってくれば削除完了。

---


# TODO

make でシェルコマンドをまとめる