shellscript
差分
このページの2つのバージョン間の差分を表示します。
| 両方とも前のリビジョン前のリビジョン次のリビジョン | 前のリビジョン | ||
| shellscript [2021/09/29 06:27] – [bash] nullpon | shellscript [2025/10/31 02:06] (現在) – nullpon | ||
|---|---|---|---|
| 行 3: | 行 3: | ||
| ===== bash ===== | ===== bash ===== | ||
| - | シェルスクリプトは基本的にはbashをターゲットに作成する。 | + | シェルスクリプトはbashをターゲットに作成する。POSIX互換のシェルの方がポータビリティが高いが今時bashがない環境は少ない。 |
| < | < | ||
| 行 11: | 行 11: | ||
| </ | </ | ||
| - | shebangは''# | + | そんなbashがない環境の代表がalpine。dockerでシェルスクリプトを起動するならalpineを避けてdebianやubuntuをベースにすると良い。 |
| + | |||
| + | ===== シェルスクリプトの実行方法 ===== | ||
| + | |||
| + | - '' | ||
| + | - '' | ||
| + | - 実行権限を付与して直接実行(普段はこれ) | ||
| + | |||
| + | ==== sourceコマンドまたは. ==== | ||
| + | |||
| + | ファイル内に定義されているシェル関数や変数をシェルにロードする目的で使用する | ||
| + | |||
| + | <code sh> | ||
| + | HOGE=' | ||
| + | |||
| + | p() { | ||
| + | echo " | ||
| + | } | ||
| + | |||
| + | p | ||
| + | </ | ||
| + | |||
| + | これを実行すると、スクリプト終了後もpやHOGEがシェルに残る。 | ||
| + | |||
| + | <code sh> | ||
| + | $ source ./ | ||
| + | 1 | ||
| + | $ echo $HOGE | ||
| + | 1 | ||
| + | $ p | ||
| + | 1 | ||
| + | $ HOGE=2 | ||
| + | $ p | ||
| + | 2 | ||
| + | </ | ||
| + | |||
| + | '' | ||
| + | |||
| + | なお'' | ||
| + | |||
| + | <code sh> | ||
| + | $ . ./hoge.sh | ||
| + | $ . hoge.sh | ||
| + | </ | ||
| + | |||
| + | ==== bash, zshの引数として実行 ==== | ||
| + | |||
| + | |||
| + | 意図がなければ基本的には避けるべき実行方法 | ||
| + | |||
| + | <code sh> | ||
| + | $ bash sample.sh | ||
| + | </ | ||
| + | |||
| + | UNIXスクリプトは実行するシェル・ランタイムをshbangで指定する。以下のスクリプトはzshを想定しておりbashでは正しく動作しない、またはエラーになる可能性がある | ||
| + | |||
| + | <code sh> | ||
| + | #!/bin/zsh | ||
| + | |||
| + | name=" | ||
| + | echo ${name:u} | ||
| + | </ | ||
| + | |||
| + | < | ||
| + | $ zsh hoge.sh | ||
| + | HELLO | ||
| + | $ bash hoge.sh | ||
| + | hello | ||
| + | </ | ||
| + | |||
| + | 逆に自分がシェルスクリプトを書くときも何も考えず'' | ||
| + | |||
| + | ==== 実行権限を付与して直接実行 ==== | ||
| + | |||
| + | 普通はこれで実行する | ||
| + | |||
| + | <code sh> | ||
| + | $ chmod +x sample.sh | ||
| + | $ ./sample.sh | ||
| + | </ | ||
| - | dockerで起動する場合、alpineにはbashが入ってないため、ubuntu-slimをベースイメージにする。 | ||
| ===== shの実行オプション ===== | ===== shの実行オプション ===== | ||
| 行 31: | 行 109: | ||
| ===== testコマンド ===== | ===== testコマンド ===== | ||
| - | < | + | < |
| test -f ./hoge.txt && echo " | test -f ./hoge.txt && echo " | ||
| 行 56: | 行 134: | ||
| ==== [[ ]] ==== | ==== [[ ]] ==== | ||
| - | testコマンドのbash拡張 | + | testコマンドのbash拡張。単語分割やパス展開しないので、変数をクオートで囲む必要ない。 |
| - | 単語分割やパス展開しないので、変数をクオートで囲む必要ない | + | <code bash> |
| + | HOGE=" | ||
| - | <code sh> | + | [ $HOGE = "a b c" ] && echo " |
| - | $ HOGE=" | + | |
| - | $ [ $HOGE == "a b c" ] && echo " | + | [ "$HOGE" |
| - | bash: [: too many arguments | + | |
| - | $ [[ $HOGE == "a b c" | + | |
| - | 一致 | + | |
| - | $ HOGE=hoge.* | + | [[ $HOGE = "a b c" ]] && echo " |
| - | $ [ $HOGE == " | + | |
| - | 不一致 | + | |
| - | $ [[ $HOGE == "hoge.*" ]] && echo " | + | |
| - | 一致 | + | |
| </ | </ | ||
| + | |||
| + | <code bash> | ||
| + | HOGE=" | ||
| + | |||
| + | [ $HOGE = " | ||
| + | |||
| + | [ " | ||
| + | |||
| + | [[ $HOGE = " | ||
| + | </ | ||
| + | |||
| + | zshでは '' | ||
| ===== read ===== | ===== read ===== | ||
| 行 79: | 行 163: | ||
| read line | read line | ||
| echo $line | echo $line | ||
| + | |||
| + | プロンプトを出して入力を促す | ||
| + | |||
| + | echo -n "User Name: " | ||
| + | read username | ||
| + | echo $username | ||
| + | | ||
| + | zshでは以下のようにかける | ||
| + | |||
| + | read " | ||
| + | echo $username | ||
| + | | ||
| + | 入力値をマスクしたい場合はread -s(決定時の改行も出力されなくなるのでechoを挟むとよい) | ||
| + | |||
| + | read -s " | ||
| + | tty -s && echo | ||
| + | echo $password | shasum -a 256 | ||
| + | |||
| + | |||
| | | ||
| 標準入力が尽きるまで行を読み取る(Ctrl-DでEOFを送信) | 標準入力が尽きるまで行を読み取る(Ctrl-DでEOFを送信) | ||
| 行 107: | 行 210: | ||
| ==== シグナルのハンドリング ==== | ==== シグナルのハンドリング ==== | ||
| - | < | + | < |
| trap "echo trap sigint" | trap "echo trap sigint" | ||
| 行 119: | 行 222: | ||
| 基本はシグナルのハンドリングだが、EXITとERRという疑似シグナルが利用できる。例えばmktempで作成した一時ファイルをスクリプト終了時に削除するなどの処理をEXITと組合わせて書ける。 | 基本はシグナルのハンドリングだが、EXITとERRという疑似シグナルが利用できる。例えばmktempで作成した一時ファイルをスクリプト終了時に削除するなどの処理をEXITと組合わせて書ける。 | ||
| - | < | + | < |
| hoge=/ | hoge=/ | ||
| mktemp $hoge | mktemp $hoge | ||
| 行 158: | 行 261: | ||
| 0-9A-Za-zのランダムな文字列を作成する。mac用 | 0-9A-Za-zのランダムな文字列を作成する。mac用 | ||
| - | < | + | < |
| - | $ cat /dev/random | base64 | fold -w 16 | egrep -v " | + | cat /dev/random | base64 | fold -w 16 | egrep -v " |
| + | </ | ||
| - | $ head -c 100 /dev/random | base64 | tr -d " | + | <code bash> |
| + | head -c 100 /dev/random | base64 | tr -d " | ||
| </ | </ | ||
| セキュアな必要がないならば | セキュアな必要がないならば | ||
| - | < | + | < |
| - | $ shasum <(ls -al) | cut -d " " -f 1 | + | shasum <(ls -al) | cut -d " " -f 1 |
| </ | </ | ||
| 行 173: | 行 278: | ||
| ===== 変数参照 ===== | ===== 変数参照 ===== | ||
| - | < | + | < |
| ${HOGE: | ${HOGE: | ||
| ${HOGE: | ${HOGE: | ||
| 行 184: | 行 289: | ||
| 指定位置で切り取り | 指定位置で切り取り | ||
| - | < | + | < |
| x=abcdefg | x=abcdefg | ||
| echo ${x: | echo ${x: | ||
| 行 191: | 行 296: | ||
| 変数の値の先頭・末尾でマッチした部分を削除する | 変数の値の先頭・末尾でマッチした部分を削除する | ||
| - | < | + | < |
| x=hogehogefugafuga | x=hogehogefugafuga | ||
| 行 209: | 行 314: | ||
| 文字列置換 | 文字列置換 | ||
| - | < | + | < |
| echo ${var/ | echo ${var/ | ||
| 行 217: | 行 322: | ||
| 使用例:まとめてリネーム、拡張子まとめて変更 | 使用例:まとめてリネーム、拡張子まとめて変更 | ||
| - | < | + | < |
| $ ls | $ ls | ||
| a.txt b.txt c.txt | a.txt b.txt c.txt | ||
| 行 229: | 行 334: | ||
| 例 | 例 | ||
| - | < | + | < |
| HOGE=" | HOGE=" | ||
| echo ${HOGE# | echo ${HOGE# | ||
| 行 243: | 行 348: | ||
| コロンは何もしないビルトインコマンド | コロンは何もしないビルトインコマンド | ||
| - | < | + | < |
| : hogehoge | : hogehoge | ||
| </ | </ | ||
| 行 249: | 行 354: | ||
| 変数HOGEが空だった場合、nyanを代入する | 変数HOGEが空だった場合、nyanを代入する | ||
| - | < | + | < |
| : ${HOGE: | : ${HOGE: | ||
| </ | </ | ||
| 行 255: | 行 360: | ||
| 変数HOGEが空だった場合、Error HOGE is emptyと出力して終了 | 変数HOGEが空だった場合、Error HOGE is emptyと出力して終了 | ||
| - | < | + | < |
| : ${HOGE:?" | : ${HOGE:?" | ||
| </ | </ | ||
| 行 261: | 行 366: | ||
| 可読性を考えると普通にifで書いた方がいいかも… | 可読性を考えると普通にifで書いた方がいいかも… | ||
| - | < | + | < |
| - | if [ -z "${HOGE}" | + | if [[ -z ${HOGE} |
| echo "Error HOGE is empty" >&2 | echo "Error HOGE is empty" >&2 | ||
| fi | fi | ||
| 行 280: | 行 385: | ||
| ファイルディスクリプタ0番がterminalに紐づいている(=パイプやリダイレクトによるデータの入力がされていない) | ファイルディスクリプタ0番がterminalに紐づいている(=パイプやリダイレクトによるデータの入力がされていない) | ||
| - | < | + | < |
| if [ -t 0 ]; then | if [ -t 0 ]; then | ||
| # パイプやリダイレクトされてない | # パイプやリダイレクトされてない | ||
| 行 297: | 行 402: | ||
| '' | '' | ||
| - | < | + | < |
| # arg1.sh | # arg1.sh | ||
| echo $# | echo $# | ||
| 行 304: | 行 409: | ||
| </ | </ | ||
| - | < | + | < |
| $ ./arg1.sh a b c d | $ ./arg1.sh a b c d | ||
| 4 | 4 | ||
| 行 314: | 行 419: | ||
| '' | '' | ||
| - | < | + | < |
| # arg2.sh | # arg2.sh | ||
| echo $@ | echo $@ | ||
| 行 320: | 行 425: | ||
| </ | </ | ||
| - | < | + | < |
| $ ./arg2.sh 1 2 3 | $ ./arg2.sh 1 2 3 | ||
| 1 2 3 | 1 2 3 | ||
| 行 326: | 行 431: | ||
| </ | </ | ||
| - | '' | + | '' |
| - | < | + | |
| + | '' | ||
| + | |||
| + | < | ||
| # arg3.sh | # arg3.sh | ||
| node -p -e ' | node -p -e ' | ||
| 行 337: | 行 445: | ||
| </ | </ | ||
| - | < | + | < |
| $ ./arg3.sh 1 2 3 | $ ./arg3.sh 1 2 3 | ||
| 1 2 3 | 1 2 3 | ||
| 行 347: | 行 455: | ||
| '' | '' | ||
| - | < | + | < |
| # arg4.sh | # arg4.sh | ||
| echo " | echo " | ||
| 行 354: | 行 462: | ||
| </ | </ | ||
| - | < | + | < |
| $ ./arg4.sh 1 2 3 | $ ./arg4.sh 1 2 3 | ||
| 1 2 3 | 1 2 3 | ||
| 行 364: | 行 472: | ||
| ===== ヒアドキュメント ===== | ===== ヒアドキュメント ===== | ||
| - | ==== 変数に格納 | + | 変数に格納 |
| - | < | + | < |
| - | hoge=$(<< ' | + | val=$(cat << ' |
| - | a = ARGV.first.split(" | + | hoge |
| - | puts a.gsub(/ | + | fuga |
| + | piyo | ||
| EOS | EOS | ||
| ) | ) | ||
| + | </ | ||
| + | |||
| + | |||
| + | 標準入力に渡す | ||
| + | |||
| + | <code bash> | ||
| + | while read -r line | ||
| + | do | ||
| + | echo $line | ||
| + | done << ' | ||
| + | hoge | ||
| + | fuga | ||
| + | piyo | ||
| + | EOS | ||
| + | ) | ||
| + | </ | ||
| + | |||
| + | |||
| + | 一度変数を経由する。''<<<'' | ||
| + | |||
| + | <code bash> | ||
| + | val=$(cat << ' | ||
| + | hoge | ||
| + | fuga | ||
| + | piyo | ||
| + | EOS | ||
| + | ) | ||
| + | |||
| + | while read -r line | ||
| + | do | ||
| + | echo $line | ||
| + | done <<< | ||
| + | </ | ||
| + | |||
| + | クオートの有無は変数展開するかしないか | ||
| + | |||
| + | <code bash> | ||
| + | val=' | ||
| + | |||
| + | while read -r line | ||
| + | do | ||
| + | echo $line | ||
| + | done << " | ||
| + | ${val} | ||
| + | ${val} | ||
| + | ${val} | ||
| + | EOF | ||
| + | </ | ||
| + | |||
| + | クオートありの場合は変数展開されずに以下のように出力される | ||
| + | |||
| + | < | ||
| + | ${val} | ||
| + | ${val} | ||
| + | ${val} | ||
| </ | </ | ||
shellscript.1632896826.txt.gz · 最終更新: by nullpon