shellscript
差分
このページの2つのバージョン間の差分を表示します。
両方とも前のリビジョン前のリビジョン次のリビジョン | 前のリビジョン | ||
shellscript [2023/11/17 01:50] – [ヒアドキュメント] nullpon | shellscript [2025/10/11 16:48] (現在) – nullpon | ||
---|---|---|---|
行 3: | 行 3: | ||
===== bash ===== | ===== bash ===== | ||
- | シェルスクリプトは基本的にはbashをターゲットに作成する。 | + | シェルスクリプトはbashをターゲットに作成する。POSIX互換のシェルの方がポータビリティが高いが今時bashがない環境は少ない。 |
< | < | ||
行 11: | 行 11: | ||
</ | </ | ||
- | shebangは''# | + | そんなbashがない環境の代表がalpine。dockerでシェルスクリプトを起動するならdebianやubuntuが良いだろう |
- | dockerで起動する場合、alpineにはbashが入ってないため、ubuntu-slimをベースイメージにする。 | ||
===== shの実行オプション ===== | ===== shの実行オプション ===== | ||
行 31: | 行 30: | ||
===== testコマンド ===== | ===== testコマンド ===== | ||
- | < | + | < |
test -f ./hoge.txt && echo " | test -f ./hoge.txt && echo " | ||
行 56: | 行 55: | ||
==== [[ ]] ==== | ==== [[ ]] ==== | ||
- | testコマンドのbash拡張 | + | testコマンドのbash拡張。単語分割やパス展開しないので、変数をクオートで囲む必要ない。 |
- | 単語分割やパス展開しないので、変数をクオートで囲む必要ない | + | <code bash> |
+ | HOGE=" | ||
- | <code sh> | + | [ $HOGE = "a b c" ] && echo " |
- | $ HOGE=" | + | |
- | $ [ $HOGE == "a b c" ] && echo " | + | |
- | bash: [: too many arguments | + | |
- | $ [[ $HOGE == "a b c" ]] && echo " | + | |
- | 一致 | + | |
- | $ HOGE=hoge.* | + | [ "$HOGE" |
- | $ [ $HOGE == "hoge.*" ] && echo " | + | |
- | 不一致 | + | [[ $HOGE = "a b c" ]] && echo " |
- | $ [[ $HOGE == "hoge.*" ]] && echo " | + | |
- | 一致 | + | |
</ | </ | ||
+ | |||
+ | <code bash> | ||
+ | HOGE=" | ||
+ | |||
+ | [ $HOGE = " | ||
+ | |||
+ | [ " | ||
+ | |||
+ | [[ $HOGE = " | ||
+ | </ | ||
+ | |||
+ | zshでは '' | ||
===== read ===== | ===== read ===== | ||
行 126: | 行 131: | ||
==== シグナルのハンドリング ==== | ==== シグナルのハンドリング ==== | ||
- | < | + | < |
trap "echo trap sigint" | trap "echo trap sigint" | ||
行 138: | 行 143: | ||
基本はシグナルのハンドリングだが、EXITとERRという疑似シグナルが利用できる。例えばmktempで作成した一時ファイルをスクリプト終了時に削除するなどの処理をEXITと組合わせて書ける。 | 基本はシグナルのハンドリングだが、EXITとERRという疑似シグナルが利用できる。例えばmktempで作成した一時ファイルをスクリプト終了時に削除するなどの処理をEXITと組合わせて書ける。 | ||
- | < | + | < |
hoge=/ | hoge=/ | ||
mktemp $hoge | mktemp $hoge | ||
行 177: | 行 182: | ||
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 |
</ | </ | ||
行 192: | 行 199: | ||
===== 変数参照 ===== | ===== 変数参照 ===== | ||
- | < | + | < |
${HOGE: | ${HOGE: | ||
${HOGE: | ${HOGE: | ||
行 203: | 行 210: | ||
指定位置で切り取り | 指定位置で切り取り | ||
- | < | + | < |
x=abcdefg | x=abcdefg | ||
echo ${x: | echo ${x: | ||
行 210: | 行 217: | ||
変数の値の先頭・末尾でマッチした部分を削除する | 変数の値の先頭・末尾でマッチした部分を削除する | ||
- | < | + | < |
x=hogehogefugafuga | x=hogehogefugafuga | ||
行 228: | 行 235: | ||
文字列置換 | 文字列置換 | ||
- | < | + | < |
echo ${var/ | echo ${var/ | ||
行 236: | 行 243: | ||
使用例:まとめてリネーム、拡張子まとめて変更 | 使用例:まとめてリネーム、拡張子まとめて変更 | ||
- | < | + | < |
$ ls | $ ls | ||
a.txt b.txt c.txt | a.txt b.txt c.txt | ||
行 248: | 行 255: | ||
例 | 例 | ||
- | < | + | < |
HOGE=" | HOGE=" | ||
echo ${HOGE# | echo ${HOGE# | ||
行 262: | 行 269: | ||
コロンは何もしないビルトインコマンド | コロンは何もしないビルトインコマンド | ||
- | < | + | < |
: hogehoge | : hogehoge | ||
</ | </ | ||
行 268: | 行 275: | ||
変数HOGEが空だった場合、nyanを代入する | 変数HOGEが空だった場合、nyanを代入する | ||
- | < | + | < |
: ${HOGE: | : ${HOGE: | ||
</ | </ | ||
行 274: | 行 281: | ||
変数HOGEが空だった場合、Error HOGE is emptyと出力して終了 | 変数HOGEが空だった場合、Error HOGE is emptyと出力して終了 | ||
- | < | + | < |
: ${HOGE:?" | : ${HOGE:?" | ||
</ | </ | ||
行 280: | 行 287: | ||
可読性を考えると普通にifで書いた方がいいかも… | 可読性を考えると普通にifで書いた方がいいかも… | ||
- | < | + | < |
- | if [ -z "${HOGE}" | + | if [[ -z ${HOGE} |
echo "Error HOGE is empty" >&2 | echo "Error HOGE is empty" >&2 | ||
fi | fi | ||
行 299: | 行 306: | ||
ファイルディスクリプタ0番がterminalに紐づいている(=パイプやリダイレクトによるデータの入力がされていない) | ファイルディスクリプタ0番がterminalに紐づいている(=パイプやリダイレクトによるデータの入力がされていない) | ||
- | < | + | < |
if [ -t 0 ]; then | if [ -t 0 ]; then | ||
# パイプやリダイレクトされてない | # パイプやリダイレクトされてない | ||
行 316: | 行 323: | ||
'' | '' | ||
- | < | + | < |
# arg1.sh | # arg1.sh | ||
echo $# | echo $# | ||
行 323: | 行 330: | ||
</ | </ | ||
- | < | + | < |
$ ./arg1.sh a b c d | $ ./arg1.sh a b c d | ||
4 | 4 | ||
行 333: | 行 340: | ||
'' | '' | ||
- | < | + | < |
# arg2.sh | # arg2.sh | ||
echo $@ | echo $@ | ||
行 339: | 行 346: | ||
</ | </ | ||
- | < | + | < |
$ ./arg2.sh 1 2 3 | $ ./arg2.sh 1 2 3 | ||
1 2 3 | 1 2 3 | ||
行 345: | 行 352: | ||
</ | </ | ||
- | '' | + | '' |
- | < | + | |
+ | '' | ||
+ | |||
+ | < | ||
# arg3.sh | # arg3.sh | ||
node -p -e ' | node -p -e ' | ||
行 356: | 行 366: | ||
</ | </ | ||
- | < | + | < |
$ ./arg3.sh 1 2 3 | $ ./arg3.sh 1 2 3 | ||
1 2 3 | 1 2 3 | ||
行 366: | 行 376: | ||
'' | '' | ||
- | < | + | < |
# arg4.sh | # arg4.sh | ||
echo " | echo " | ||
行 373: | 行 383: | ||
</ | </ | ||
- | < | + | < |
$ ./arg4.sh 1 2 3 | $ ./arg4.sh 1 2 3 | ||
1 2 3 | 1 2 3 | ||
行 385: | 行 395: | ||
変数に格納 | 変数に格納 | ||
- | < | + | < |
val=$(cat << ' | val=$(cat << ' | ||
hoge | hoge | ||
行 397: | 行 407: | ||
標準入力に渡す | 標準入力に渡す | ||
- | < | + | < |
while read -r line | while read -r line | ||
do | do | ||
行 412: | 行 422: | ||
一度変数を経由する。''<<<'' | 一度変数を経由する。''<<<'' | ||
- | < | + | < |
val=$(cat << ' | val=$(cat << ' | ||
hoge | hoge | ||
行 428: | 行 438: | ||
クオートの有無は変数展開するかしないか | クオートの有無は変数展開するかしないか | ||
- | < | + | < |
val=' | val=' | ||
shellscript.1700185816.txt.gz · 最終更新: by nullpon