bash操作・シェルスクリプトについて学んだのでメモ。
ファイル操作系コマンド
# カレントディレクトリの確認
pwd
# change directory
cd [path]
# ls:ファイル一覧
ls
# la -la
# -l:ファイルのサイズや更新日時を含めた一覧
# -a:隠しファイルを含めた一覧
ls -la
フォルダ/ファイルの操作
# mkdir:フォルダ作成
mkdir [dir]
# mkdir -p:深いディレクトリを一気に作成
mkdir -p learning/log/20190422.md
# touch:ファイル作成
touch [file]
# rm:ファイル・ディレクトリの削除
rm (option) [削除するファイル1] [削除するファイル2] ...
# rm -i:「本当に削除しますか?」と確認してくれる
# rm -r:フォルダを削除できる
# rmdir:空のディレクトリを削除する
rmdir [dir] # 空でないディレクトリを指定するとエラーになる
# mv:ファイル・ディレクトリを移動する/名前を変更する
mv (option) [移動元] [移動先]
ファイルの内容を表示
# cat:ファイルの内容を表示
cat [file]
# head:ファイルの最初の10行を表示
head [file]
その他のコマンド
curl:URLへのアクセス・ダウンロード
curl -o <ファイル名> <URL>
-o
でファイルへの書き出し
# ダウンロード
curl -o hogehoge.tar.gz http://xxxxxxxxxxx.jp/hogehoge.tar.gz
# 解凍
tar xzf hogehoge.tar.gz
find:ディレクトリツリーからファイルを探す
find <検索開始ディレクトリ> <検索条件> <アクション>
# カレントディレクトリで,.txtファイルを調べ,パスを表示(print)する
find . -name "*.txt" -print
ヘルプ
# ヘルプ
[command] --help
# マニュアル
man [command]
# コマンドのフルパスを表示する
which [command]
# printenv:環境変数の表示
printenv
# あるいは特定の変数を指定してecho
echo $LANG
# export:環境変数の設定
export LANG='ja_JP.UTF-8'
- 改行コードがCRLFで作成すると,Linuxは改行コードがLFなので,エラーになる
#!/bin/bash:シバン
シェルスクリプトを作るとき,最初の行に以下のように書く必要があるらしい。
#!/bin/bash
これは,その.shファイルを,/bin/bashで実行するよう指示していることになる(Linuxカーネルは#!の後ろのコマンドを実行する)。
つまり,以下のようなコマンドラインが実行されているということになる
$ /bin/bash ./hoge.sh
いろんな実行方法があるらしい。
①シェルの引数として実行する
bashから実行させる。shファイルに実行権限は不要
bash hoge.sh
②sourceコマンドを利用して実行する
sourceコマンド,あるいはドットコマンドで実行できる
sourceコマンドでは直接実行するわけではないので,shファイルに実行権限は不要
source ./hoge.sh
. ./hoge.sh
ドットコマンドは古いやり方だし,見落として妙なトラブルを引き起こしかねないため非推奨らしい
③ファイル名のみを指定して実行する
シェルスクリプトに実行権限を付与すると,sourceコマンドが不要になる
# 実行権限の付与
chmod +x hoge.sh
# 実行
./hoge.sh
変数
変数に関しての注意点
- 代入するときは
=
の前後にスペースを入れてはならない
- 代入時は$をつけないが,呼び出すときは$をつける
$():コマンド置換
コマンド置換$()
により,コマンドの結果を文字列として受け取る
# dateコマンドで取得した日付を文字列として受け取る
today=$(date '+%Y-%m-%d')
${}:変数を文字列に埋め込む
"string${var}string"
例
# 今日の日付
today=$(date "+%Y年%m月%d日")
# 文字列の結合
message="今日は${today}です!"
# 表示
echo $message
if文とfor文
if文
if 文と test コマンド | UNIX & Linux コマンド・シェルスクリプト リファレンス
testコマンド
論理演算はtestコマンドか[コマンドを使う。次のif文は同じ意味になる。
if [ "$1" = "bin" ]; then
if test "$1" = "bin"; then
※シェルスクリプトでは,ifの後に置くのは条件式ではなくコマンドである
$ type [
[ is a shell builtin
例
hoge="A"
fuga="A"
if [ $hoge -eq $fuga ]; then # -eqと=は同じ意味の論理演算子
echo "文字列は同じです"
else
echo "文字列は違います"
fi
for文
例
shell - How do I iterate over a range of numbers defined by variables in Bash? - Stack Overflow
for i in {1..5}
do
echo $i # 変数iの値を表示
done
1
2
3
4
5
例:Fizz Buzz
for ((i=1;i <= $N;i++))
でC言語風に1からNまで1ずつ変化するi を指定できる
$((計算式))
で計算でき,剰余は%
で計算する
#!/bin/bash
N=30
for ((i=1;i <= $N;i++)); do
if [ $(($i % 15)) = 0 ]; then
echo "Fizz Buzz"
elif [ $(($i % 5)) = 0 ]; then
echo "Buzz"
elif [ $(($i % 3)) = 0 ]; then
echo "Fizz"
else
echo $i
fi
done
配列
bash 配列まとめ - Qiita
# 空の配列の生成
empty_array=()
# 先頭に追加
array=(3 "${array[@]}") # array は (3 “a” "b" "c")
# 末尾に追加
array=("${array[@]}" 4) # array は (3 "a" "b" "c" 4)
array+=( 5 ) # array は (3 "a" "b" "c" 4 5)
例:lsコマンドの中身を配列にして表示する
#!/bin/bash
array=()
for i in `ls`; do
array+=( $i )
done
echo ${array[@]}
例:その日の日付をファイル名に含んだ空のファイルを作成する
#!/bin/bash
# 保存先
directory="./log"
# カレントディレクトリの移動
cd ${directory}
# ファイル名
today=$(date "+%Y%m%d")
filename="log_${today}.log"
# もしファイルがなければ作成する
if [ -e $filename ]; then
echo "既にファイルが存在します。"
else
touch "${filename}"
echo "${directory}に${filename}を作成しました。"
fi
引数
コマンドの引数は,コマンドからスペースを空けて記述していく。
bash hoge.sh 引数1 引数2 ... 引数n
$0, $1, ..., $n
で参照できる
$@
:すべての引数を1行であつかうが,それぞれ別の文字列
$*
:引数を分割せず,スペース区切りされた1つの文字列とする
$#
で指定されたパラメータの数がカウントされる
./hoge.sh *
のように*
を指定すると,カレントディレクトリにあるファイル達の名前がパラメータに入る
例:引数をそのままechoする
#!/bin/bash
echo "指定された引数(\$@):$@"
echo "指定された引数の数(\$#):$#"
標準入力・出力
read:標準入力
入力と出力 | UNIX & Linux コマンド・シェルスクリプト リファレンス
cat
でファイル名を指定しない場合,標準入力を受け取ってechoする動きをするようになる
read
コマンドで標準入力を受け取るようになる
# 標準入力の受け取り
read [変数名]
# 入力された内容は[変数名]の変数に格納される
echo $[変数名]
echo:標準出力
# 標準出力
echo [object]
例
$ echo Hello World
Hello World
リダイレクト
# 標準入力
cat < [file]
# 標準出力
ls > ls.txt
## >:上書き,>>:末尾に追記
ls -la >> ls.txt
# 標準エラー出力
ls /xxx 2> error.txt
- 上のコードで作られた
ls.txt
はメモ帳で開くと改行が無いが,cat < ls.txt
すると改行されて表示される
その他の概念
パイプライン
- コマンドからの標準出力を,別のコマンドの標準入力に入れる
# ls -laの結果をlessで表示する
ls -la | less
例:相対パス・絶対パスをパラメータで渡し、渡されたファイルパスが相対か絶対かを判定する
#!/bin/bash
# 第一引数にパスを入れてもらう
if [ $# != 1 ]; then
echo "第一引数に判定したいパスを入れてください。"
else
# 1文字目を取り出す
first_letter=$( echo $1 | cut -c 1 )
if [ $first_letter = "/" ]; then
echo "絶対パスです。"
else
echo "相対パスです。"
fi
fi
文字列操作
grep [オプション] <検索パターン> <ファイル名>
# シェルスクリプトを検索
ls -la | grep .sh
文字列置換
sed "s/置換対象にしたいパターン/置き換えたい新しいパターン"
変数内文字列置換
${変数/検索文字列/置換文字列}
参考
この本を参考にしていました。この一冊で全部をまかなえる…とまでは行きませんが,多くの基本的なコマンドをカバーしている上,「なぜこうするのか」についての説明もあったりして,いい本でした。