zshを使ってます。
まだ途中だけどとりあえず投下して追記していきたい。。。
##参考
【初心者向け】シェルスクリプトの作り方と実行方法
スクリプト中で実行しているコマンドを表示する
実用的なシェルスクリプト
シェルスクリプト
【簡単】シェルスクリプトでテキストを改行する方法
bashのif文でワイルドカード・正規表現を用いて条件判断をさせる | 俺的備忘録 〜なんかいろいろ〜
bashのsetコマンドで覚えておきたい使い方9個 | 俺的備忘録 〜なんかいろいろ〜
シェルスクリプトで複数行のコメントアウト
Shell 特殊変数 - Qiita
Bashの便利な構文だがよく忘れてしまうものの備忘録 - Qiita
Tips
#!/usr/bin/zsh
これはスクリプトの一行目に記述する定型文。
この一行目で、実行時どのシェルでスクリプトを実行するかが決まる。
(bashやzshの独自機能を使わないのであれば#!/usr/sh
でいいっぽい)
zsh -x test.sh
-x オプションを付けてシェル実行(例としてtest.shを実行)すると
shファイル内に記述されたコマンドも含めて表示する(デバッグ用途?)。
:
if文分岐内容などで何もしない処理
を表す。
実際のコードで「何もしないから何も書かない」でいるとエラーになるので
エラー回避のための記述になる。
コメントアウト
echo hoge
# echo "ここは実行されない"
echo piyo
複数行の場合は << 任意の文字列 で複数行を括る。
コメントアウト終了部分には << は記述不要
echo hoge
<< COMMENT
echo "ここは実行されない"
echo "実行されないんですよ!"
COMMENT
#!/bin/bash シェルスクリプト名.sh
シェルスクリプト1行目のコメントアウトは
bash(を起動させるため)のパス指定として機能している。(ただのコメントアウトではない)
ここの記述がおかしいと(パスが違うので)実行権つけてもスクリプト名だけで実行ができなかったり
そもそもシェル内で使用できる記述形式が変化したり (結果エラーwww) する。
スクリプト名取得
echo "$0" #シェル名のフルパス出力
echo "$(basename $0)" #シェル名だけ出力
# /home/huga/hoge.sh
# hoge.sh
引数
シェルスクリプトや関数等に渡す値。
任意の値をスクリプトや関数に引き継がせて処理を進めたいときなどに使用。
# スクリプト名.sh 引数
sample.sh arg
echo "$*"
# 変数に入れてから表示させる
list=($*)
echo "${list[*]}"
#!/bin/bash array2.sh
[[ $# -eq 0 ]] && echo "nothing" | command return
function calc_one(){
sum=0
for c in "$@"; do sum=$(($sum + $c)); done
echo "$sum"
}
result=`calc_one $*`
echo "$result"
$ array2.sh 1 2 3
6
echo "$#" # 引数の数
echo "$1" # 1つ目の引数の内容
echo "$*" # 全引数の内容
echo "$@" # 全引数の内容
$ sample.sh a b c d e
5
a
a b c d e
a b c d e
#変数
宣言時は
fff_fff=""
のように記述(=
間のスペースは空けない)
呼出し時は$つけて
$fff_fff
変数にコマンド内容を設定する場合は
cmd=`cd ~/$HOME`
のようにバッククォートでコマンド部分を挟んで記述
ファイルのパスを取得する(相対/絶対)
#dirname ${0}
path=`dirname ${0}`
echo $path
#cd $(dirname ${0}) && pwd
filepath=`cd $(dirname ${0}) && pwd`
echo $filepath
四則演算
echo $((1 + 2)) # 足し算
echo $((3 - 4)) # 引き算
echo $((5 * 6)) # かけ算
echo $((8 / 7)) # 割り算(割り切れない場合は小数以下が消える)
echo $((10 % 9)) # 剰余
echo $((11 ** 12)) # 階乗
echo $((114+514))
数字の判定
-gt -ge -eq -le -lt
> >= = <= <
-eq # = equal 等しい
-gt # > greater than
-ge # >= greater than or equal
-lt # < less than
-le # <= less than or equal
#関数
#記述形式
testKansu(){
echo "処理内容"
}
#呼び出し
testKansu
#コマンドあれこれ
###read
#入力を受け付ける
read HENSU
echo $HENSU
#文字表示と組み合わせる場合
read -p "何か入力してください" ANSWER
echo $ANSWER
ecco -n "何か入力してください"; read ANSWER
[[ -n $ANSWER ]] && echo $ANSWER #入力がない場合、実行されない
funcOne(){
echo "おはよう! "$HIKISU"ぎ君"
echo -e "さよなら! ${HIKISU}ぎ君\nそいつは $1ぎだ!"
}
read -p "何か入力してください" HIKISU
funcOne $HIKISU #入力内容を引数にして関数に投げたりできる
コマンドを繋げて実行(セミコロン アンパサント x2 パイプ x2)
; 複数のコマンドを1行で記述して繋げて実行
&& 先のコマンドが真で完了(true 成功)した際に次のコマンドを実行
|| 先のコマンドが偽で終了(false 失敗)した際に次のコマンドを実行
# ; セミコロン前後のスペースは割と曖昧でも実行できる
pwd;ls
pwd; ls
pwd ;ls
pwd ; ls
pwd ; ls
pwd ; ls
# ; 何個でもぉ 連結可能
echo;pwd;echo;uname;hostname
# && 先のコマンドが成功すれば続けて後のコマンドを実行
mkdir test_01 && cd $_
# || 簡単なtestコマンドなら1行で書ける
a=1;test $a -eq 2 || echo no
echo 'Hoge!';pwd;ls -l
# 文字列括りにダブルクォーテーション(")を使うと
# 含まれる文字列によっては実行結果がおかしくなるので注意
echo "Hoge!, \
tororo ms\
--nkb."
# Hoge!, tororo ms--nkb.
リダイレクト
ファイル内容を初期化
: > test.txt
標準出力に表示させずにコマンド実行 /dev/null
コマンドは実行させたいが、余計な結果出力を省きたい場合に使用
&>/dev/null
ls &>/dev/null
# ls >/dev/null 2>&1
>/dev/null
ls >/dev/null
# ls 1>/dev/null
その他
# 追記 >>
echo 'hoge' >> test.txt
# 強制上書き >| or >!
echo 'important' >| test.txt
echo 'important' >! test.txt
# 強制追記 >>| or >>!
echo 'important add' >>| test.txt
echo 'important add' >>! test.txt
※ 強制上書きは危険なので注意
※ シェルによっては >!
は使えなかったり
#if文記述(testコマンド)
testコマンドで条件判定できる。[] で囲むとtestコマンドと同じ効果になる。
if文は基本的に [] を利用して条件式を記述する。
if []
= test
if [ "$1" == "piyo" ]
= test "$1" == "piyo"
if [ "$1" == "piyo" ]; then
echo "TRUE"
elif [ "$url" == "katu" ]&&[ "$url" == "dearu" ]; then
echo "AND条件"
elif [ "$url" == "mosikuha" ] || [ "$url" == "matawa" ]; then
echo "OR条件"
else
:
fi
#値(場所)が存在する
[ -e ~/nanyanen/honma ] && echo "aruyo"
#値(場所)が存在しない
[ ! -e ~/nandeyanen/ahoka ] && echo "naiyo--"
#値がある(空でない)1
[ -n $nokara ] && echo $ataiari
#値が空である
[ -z $atai ] && echo $karadesu
#参照したファイルの中身が0バイトではない
[ -s $file ] && echo $nakamiGAarimasu
#ファイルか判定
[ -f $file ] && echo "file desuyo."
#ディレクトリか判定
[ -d $dir ] && echo "directory desuyo."
#ファイルが存在し、実行権限が付与されている
[[ -x `which hoge` ]] && echo "hoge dekiruyo."
# || で else文を設定できる
[ $hoge = $foo ] && echo "true" || echo "false"
# [[ ]] で囲えば 複数条件を記述可能
[[ ! -z $hoge && $piyo == "foo" ]] && out=` > $bar`
for文
for i in a a a; do echo bbb; done
# bbb
# bbb
# bbb
arr=(el psy cong lue)
for i in ${arr[@]}
do
echo $i
done
#el
#psy
#cong
#lue
引数全て = $*
"$@"
for c in $*; do echo $c; done
for c in "$@"; do echo $c; done
if [[ -n $* ]]; then
for content in $*
do echo $content
done
fi
while文
while 条件式
do
…
break
…
done
# hige 以外はお断り
while :
do
read key
[[ $key = hige ]] && break
done
clear
echo "髭!"
# hige を打っても終われない
while :;do read key;[[ $key = hige ]] && continue; done
while :
do
read key
exit
done
echo "じゃあの"
# while 条件式; コマンド ; done
while true ; do ps aux | grep httpd ; echo ""; sleep 2 ; done ;
while sleep 1; ls -l | wc -l ; done
while read line; do echo "${line}" done < text.txt
case文
条件部分はクォート囲みありでもなしでもおk
case $1 in
# 条件 ) コマンド ;;
1 ) echo "(・・)" ;;
"3" ) echo "(・・)(・・)(・・)" ;;
8 ) echo "(・・) x 8" ;;
* ) echo $1 ;;
esac
while :
do
read key
case "$key" in
"q" ) echo "break で終了";break ;;
"a" ) echo "$keyやろ" ;;
??l* ) echo "3文字目がlやろ" ;;
hoge ) echo "${key}やろ!" ;;
hige ) echo "髭!" ;;
94 ) echo "$key-95=-1" ;;
[hH]* | [pP]* ) echo "$key 先頭が h or H or p or P の文字列" ;;
[A-Z]* ) echo "$key 先頭が大文字の文字列" ;;
* ) echo "$key (・⊇・)?" ;;
esac
done
コマンドで条件分岐
するにはバッククォート
で括る
ASTERISK="*"
# case `コマンド` in
case `echo $(($RANDOM % 100))` in
8* ) echo " 8なんとか" ;;
9* ) echo " ほぼ100? ほぼ10?" ;;
*5 ) echo " 5の倍数" ;;
* | $ASTERISK ) echo " (・⊇・)?" ;;
esac
日時を利用
# 年月日時分秒
echo `date +%Y%m%d%H%M%S`
touch test`date +%Y%m%d`.txt
指定の数値分だけ出力
for i in {1..10}; do echo $i; done
算術式展開
x=2
y=5
sum=$((x+y))
echo $sum
#7
echo $((x+y))
#7
#!/bin/bash
i=1
sum=0
while [[ $i -le 100 ]]; do ((sum=sum+i)); ((i+=1)); done
echo $sum
#!/bin/bash
sum=0
for a in {1..100}; do ((sum=sum+a)); done
echo $a
配列
arr=(hoge hoge2 hoge3)
echo ${#arr[*]}
# 3
echo ${#arr[@]}
# 3
echo ${#arr[1]}
# 2
echo ${arr[2]}
# hoge3
hoges="p pk piyo"
echo $hoges
# p pk piyo
arr=(hoge hoge2 hoge3)
key_max=$((${#arr[*]} - 1)) #添字の最大値を取得
文字列の切り出し(cut)
# cut -d "区切り文字" -f 何列目
date
#> Sun Dec 14 20:11:45 JST 2018
## 時刻(時分秒)を 切り出し
date | cut -d " " -f 4
#> 20:11:45
## さらに 時間(hour)だけ 切り出し
date | cut -d " " -f 4 | cut -d: -f 1
#> 20
特殊記号
$#・・・・・・シェルスクリプト実行時の引数の数
$@,$*・・・シェルスクリプト実行時の全引数の変数
$$・・・・・・現在のプロセス番号(PID)
$?・・・・・・直近のコマンドの実行結果のステータスコード
0・・・・コマンド正常終了
1・・・・コマンド異常終了
2・・・・シェルスクリプトの異常終了(文法エラー、文字列の比較など)
126・・・権限のないファイルを実行した場合のエラー
127・・・"command not found" 時のエラー
130・・・強制停止(Ctl-C)時のエラー
正規表現
[[]]
で囲み、=~
を用いて正規表現でif文とかできる。
正規表現の条件にはクォーテーションを使わないように。
name=nmhogen
[[ $name =~ hoge.*$ ]] && echo hoge!
tel='09012345678'
reg='[0-9]{3}-?[0-9]{4}-?[0-9]{4}'
# 0~9 の 3文字-4文字-4文字 の組み合わせ
[[ $tel =~ $reg ]] && echo $tel
==
でも正規表現できる
if [[ `file today_memo.txt` == *text* ]]; then echo 'text-file des4os4'; fi
ランダム(乱数)
# $RANDOM を使う。シェルがbashかzshなら使える。shは使えない
echo $(($RANDOM % 10))
# 0 〜 9 でランダムに出力
# シェルの種類に関係なく乱数を使える
echo $(( $(od -vAn -N4 -tu4 < /dev/random) % 10 ))
# 0 〜 9 でランダムに出力
音(サウンドファイル)を鳴らす
yum でインストールできないかも?
# afplay サウンドファイルのパス
afplay ~/Desktop/hoge/piyo/foo.wav
## たいていの拡張子はカバーしてるっぽい?
# 再生する時間 [秒数指定] (ファイルの再生時間より長くはできない)
afplay -t 0.01 ファイルパス
afplay -t 30 ファイルパス
# 音の品質 [0/1 → 低/高] (違いがわかんね)
afplay -q 0 ファイルパス
afplay -q 1 ファイルパス
# ファイル再生(音声・時間)を圧縮する [0は通常再生(だと思う)]
afplay -r 0 ファイルパス
afplay -r 50 ファイルパス
# -v [音量] は使わないほうがいい。スピーカーからHAKAIONが鳴りうるので