Linux Shellでよく使うコマンド集
shellを書いたりターミナルへ直接コマンド打ったりするとき、ちょくちょく調べるのが面倒なのでまとめ
shファイルのテンプレート
文字コードはUTF-8, 改行コードはLF
#!/bin/sh
set -eu
set -x # コマンドをすべて出力
#trap read debug # 一行ずつ実行
#--------------------------------
# shの説明
#--------------------------------
cd `dirname $0`
# ここに色々処理を書く
echo "finish..."
それぞれの説明
どのプログラムで動かすかの宣言
単なるコメントではないです。
「binディレクトリ配下にあるshでこのファイルを動かします」の宣言、みたいな
#!/bin/sh
これを書いておくとsh xxx.sh
ではなく(実行権限をつけた上で)./xxx.sh
でも実行できるようになる
エラー発生時にshellの実行を止める
デフォルトではエラーが発生しても止まらない
set -e
止めたくないときはset +e
を実行
未定義の変数を使おうとしたときshellの実行を止める
set -u
file_path="xxx/xxx/xxx.txt"
rm ${fale_path} # スペルミスで違う変数名扱いになる
shell実行時にコマンドをすべて出力する
Windowsのコマンドプロンプトの @echo on
みたいな
set -x
# 以降はコマンドが出力される
出力をやめるとき
set +x
shellを1行ずつ実行する
set -x
trap read debug
# 以降は一行ずつ実行
shファイルがあるディレクトリに移動
Windowsのコマンドプロンプトの cd %~dp0
みたいな
cd `dirname $0`
$0
には現在実行中のshファイルへのパスがセットされている
shellの実行を一時停止する
- [Enter]以外では進まない
- メッセージは出ずに実行だけ止まるので、直前でechoするといい
echo "続けるにはEnterを入力してください"
read Wait
ファイルを一覧表示
Windowsのコマンドプロンプトの dir
みたいな
# 今いるディレクトリのファイル一覧を出力
ls
# もっと詳しく情報を出力(llと同等)
ls -l
# 指定ディレクトリを指定しての一覧表示もできる
ls xxx/xxx/
if文
if <条件式> ; then
# 条件式がtrueのとき実行
elif <条件式> ; then
# 条件式がtrueのとき実行
else
# どちらもfalseのとき実行
fi
等しいか判定
※[
の前後にはスペースを入れないとエラー
# valが数値のとき
if [ 1 -eq $val ] ; then
...(省略)
# valが文字列のとき
if [ "aaa" = $val ] ; then
等しくないことを判定
# valが数値のとき
if [ 0 -ne $val ] ; then
...(省略)
# valが文字列のとき
if [ "aaa" != $val ] ; then
shell実行時引数をチェック
引数が1つ必要な場合
# $# 引数の個数
# $0 実行したshファイルへのパス
if [ $# != 1 ]; then
echo "ex. sh $0 ファイル名"
# => ex. sh test.sh ファイル名 と出力
exit 1
fi
ファイルの存在有無を確認
1ファイルだけ探す
if [ -e ${file_path} ]; then
echo "ファイル${file_path}がありました"
fi
if [ ! -e ${file_path} ]; then
echo "ファイル${file_path}がありません"
fi
ディレクトリの存在有無を確認
if [ -d ${dir_path} ]; then
echo "ディレクトリ${dir_path}がありました"
fi
if [ ! -d ${dir_path} ]; then
echo "ディレクトリ${dir_path}がありません"
fi
正規表現にマッチするか
# 「A012」とかでマッチする
if [ `echo ${str} | grep "[A-Z][0-5]+"` ]; then
echo $str
fi
if [ ! `echo ${str} | grep "[A-Z][0-5]+"` ]; then
# マッチしないとき入る
echo $str
fi
whileループ
while <条件式>; do
# 条件式がtrueの間ループ
done
無限ループ(止めるときは [Ctrl] + C)
while true; do
echo "1秒待ってループ"
sleep 1
done
コピー
ファイルのコピー
cp ${src_path} ${dest_path}
オプションの一覧
オプション | 意味 |
---|---|
-r | (コピー元がディレクトリのとき)ディレクトリの配下をすべてコピー |
-v | コピー結果を出力(どのファイルをコピーしたか) |
-f | コピー先に同名ファイルがあるとき上書きする |
-a | サブディレクトリも含めて属性とかを可能な限り保持してコピー |
cp -r ${src_path} ${dest_path}
移動
ファイルを移動
mv ${src_path} ${dest_path}
オプションの一覧
オプション | 意味 |
---|---|
-v | 移動結果を出力(どのファイルを移動したか) |
-f | 移動先に同名ファイルがあるとき上書きする |
まとめて移動もできる
# xxx1.txt,xxx2.txtをabc/test_dir/ディレクトリへ移動
mv xxx1.txt xxx2.txt abc/test_dir/
ファイルの削除
rm ${file_path}
オプションの一覧
オプション | 意味 |
---|---|
-r | ディレクトリを削除(サブディレクトリ含めて) |
-f | 引数が存在しないファイルのとき、何もしない(すでに削除済みのときエラーにしない) |
# ディレクトリの場合
rm -r ${dir_path}
ファイルを検索
存在しないときはエラー
find <検索対象ディレクトリ> -name <検索するファイル名>
圧縮・解凍する
zipのコマンドがある場合
# 圧縮
zip xxx.zip <ファイルやディレクトリ>
# 解凍
unzip xxx.zip
アーカイブ=複数ファイルを1ファイルに固める(無圧縮)
tar -cf xxx.tar <ファイルやディレクトリ>
# 実行時にアーカイブしたファイルを出力する(vを追加)
tar -cvf xxx.tar <ファイルやディレクトリ>
# 展開
tar -xvf xxx.tar
# 展開先を指定
tar -xvf xxx.tar -C <展開先のディレクトリ>
圧縮する(実際はアーカイブ化→圧縮を順に行っている)
tar -jcf xxx.tar.bz2 <ファイルやディレクトリ>
# 実行時に圧縮したファイルを出力する(vを追加)
tar -jcvf xxx.tar.bz2 <ファイルやディレクトリ>
# 解凍
tar -jxvf xxx.tar.bz2
エスケープする
基本的にダブルクォート("aaa"
)を使えばOK
記号一覧
名前 | 記号 | 入力方法 | 動作 |
---|---|---|---|
ダブルクォート | " |
Shift + 2 |
$ 、バッククォート、バックスラッシュ以外をエスケープ |
シングルクォート | ' |
Shift + 7 | 全部エスケープ |
バックスラッシュ | \ |
\(円マーク) |
1文字だけエスケープ |
バッククォート | ` | Shift + @ | コマンドとして実行する。※エスケープ文字ではない |
str = "abc"
# ダブルクォート
echo "${str}"
# => abc
# シングルクォート
echo '${str}'
# => ${str}
ファイル名に)
とかが使われているとき、コマンドでうまく実行できないためエスケープする必要がある
# xxx(1).txtに対して実行
#cp -v xxx(1).txt ${dest_path} # NG
cp -v xxx\(1\).txt ${dest_path} # OK
コマンドの実行結果を変数に入れる
コマンドを ` (バッククォート)で囲む
# xxx.txtがあるディレクトリ名を取得
dir_name=`dirname */xxx.txt`
echo $dir_name
ディレクトリ内のファイル数をカウントする
ls -1 | wc -l
テキストファイルの操作
ファイルの中身を出力
全部出力
# ファイルの中身が一行だけで改行なしの場合、改行が出力されないので注意
cat ${file_path}
最後の数行だけ出力(ログファイルとかに使う)
tail ${file_path}
ファイルが更新されたら出力し続ける(止めるには [Ctrl] + C)
tail -f ${file_path}
(複数ファイルがあるとき)最後に更新されたファイルの中身を見る
# 取得したいファイルがあるフォルダへ移動してから実行
ls -t | head -n 1 | xargs tail -f
バイナリで出力
# 2バイト単位、16進数で出力
od -h ${file_path}
# -> 0000000 1d01 の形式
viで編集する
vi ${file_path}
操作方法
- [ESC]でコマンドモードになる
- 終了
-
:q
:保存せずに終了 -
:wq
:上書き保存して終了(書き込み可能状態でないとエラー)
-
- 編集する
-
:i
:編集モードに変更 -
x
:1文字削除
-
テキストファイルの中身を検索する
if grep -q 'str' ${file_path}; then
echo strがあります
fi
# 正規表現
if grep -E '^str$' ${file_path}; then
echo strのみの行があります
fi
テキストファイルの中身を書き換える
一致する文字列を置換する
# 置換後のファイルを別名保存
sed -e 's/置換対象の文字列/置換後の文字列/g' test.txt > test_new.txt
# 置換後のファイルを上書き保存
sed -i -e 's/置換対象の文字列/置換後の文字列/g' test.txt
一行挿入する
最終行に追加&改行
echo 'hoge'>> test.txt
# 「>」一つだと新規作成になる
echo 'hoge'> test.txt
行指定で追加
sed -e '行番号i 挿入する文字列' test.txt > test_new.txt
# 例(3行目にhogeを挿入)
sed -e '3i hoge' test.txt > test_new.txt
実行権限をつける
shやexeを実行するのに必要
chmod +x ${file_path}
パーミッションの変更
chmodの引数に「アクセスクラス」+「演算子」+「アクセス型」の組み合わせで指定する
アクセスクラス | 名前 |
---|---|
a | 下記すべて |
u | ユーザ |
g | グループ |
o | その他 |
ll
実行時に出力される rwxr-xr--
はユーザ、グループ、その他の順に3つづつ並んでいる
-
rwxr-xr--
の意味-
rwx
:ユーザに全権限を与える -
r-x
:グループに読み込みと実行権限を与える(書き込みは不可) -
r--
:その他は読み込みのみ
-
演算子 | 意味 |
---|---|
= | 指定するアクセス型に指定 |
+ | 指定するアクセス型を追加(権限を与える) |
- | 指定するアクセス型を除外(権限を除く) |
アクセス型 | 意味 |
---|---|
r | 読み込み権限 |
w | 書き込み権限 |
x | 実行権限 |
例:-rwxr-xr-x
にしたいとき
# 全部r-xにして、ユーザにだけwを追加
chmod a=r-x,u+w test.exe
数値指定のときは、アクセス型に対応する数値の合計を並べる
アクセス型 | 数値 | 意味 |
---|---|---|
r | 4 | 読み込み権限 |
w | 2 | 書き込み権限 |
x | 1 | 実行権限 |
例:-rwxr-xr-x
にしたいとき
-
rwx
= 4 + 2 + 1 = 7 -
r-x
= 4 + 1 = 5 -
r--
= 4
chmod 754 test.exe
chmodのオプション
オプション | 意味 |
---|---|
-v | 実行結果を表示 |
-c | 変更があったら実行結果を表示(変更がなければ何も出力しない) |
-R | サブディレクトリとかも変更 |
# xxxディレクトリ配下をすべて変更&変更があったら出力
chmod -cR 754 xxx/
シンボリックリンクを作成
ln -s ${dir_path} <作成するリンク名>
実行結果をコンソールに出力しない
/dev/null
へ実行結果を捨てる
unzip test.zip > /dev/null
※エラーが発生しても全部出力されないので注意
疎通確認
最後に「0% packet loss」と出れば接続成功
# 無限に出力される(Ctrl + Cで中断)
ping <IPアドレス>
# 2回確認したら終わり
ping -c2 <IPアドレス>
変数の文字置換
str=`cat xxx.txt` # xxx.txtに書かれている文字を取得
echo ${str} # -> abc/123 と出力
str=${str#*/} # 最初の/までを削除
echo ${str} # -> 123 と出力
Discussion