スクリプティング概論(シェル/シェルスクリプト)

インタフェースであるシェルと, 動作プログラムであるシェルスクリプトまとめ.

または, 簡単な雑務を簡易スクリプトでやっつけるトピックまとめ.

Basics

🐚シェル

コンピュータ上でユーザと🔖OSがやり取りするためのインタフェースを提供するプログラム.

ただし, 一般的には📝ターミナル環境で動作する🔖CLIを指すことが多い. コマンドラインシェルともいう.

さらにいえば, もともとはUNIXシェルがメジャーだったものの, 今ではWindowsでもMacOSでもLinuxでもUNIXシェルを搭載しているので, UNIXシェルを指してシェルということも多い印象.

🔖シェルスクリプト

シェルを記述するためのインタプリタ言語.

UNIXシェル

汎用言語

📝bash shell

関数

引数は, 2 で参照できる.

display () {
  echo "This is a sample function"
}

コマンド置換

“ または, $() を利用する.

$ cd /lib/modules/$(uname -r)/

引数

ParameterMeaning
$0Script name
$1First parameter
3, etc.Second, third parameter, etc.
$*All parameters
$#Number of arguments

引数チェック

引数の数をチェック

if [ $# != 1 ]; then
    echo "usage: $0 file_path" 1>&2
    exit 1
fi

ファイルやディレクトリパスが存在するか

if [ -e パス ]; then
    # 存在する場合
else
    # 存在しない場合
fi

Statements

if

In compact form, the syntax of an if statement is:

if TEST-COMMANDS; then CONSEQUENT-COMMANDS; fi

A more general definition is:

if condition
then # if condition; then
  statements
else
  statements
fi
  • condition

    ConditionMeaning
    -e fileCheck if the file exists.
    -d fileCheck if the file is a directory.
    -f fileCheck if the file is a regular file
    -s fileCheck if the file is of non-zero size.
    -g fileCheck if the file has sgid set.
    -u fileCheck if the file has suid set.
    -r fileCheck if the file is readable.
    -w fileCheck if the file is writable.
    -x fileCheck if the file is executable.
  • numerical tests

    OperatorMeaning
    -eqEqual to
    -neNot equal to
    -gtGreater than
    -ltLess than
    -geGreater than or equal to
    -leLess than or equal to

case

case expression in
   pattern1) execute commands;;
   pattern2) execute commands;;
   pattern3) execute commands;;
   pattern4) execute commands;;
   * )       execute some default commands or nothing ;;
esac

for

for variable-name in list
do
  execute one iteration for each item in the
  list until the list is finished
done

while

while condition is true
do
    Commands for execution
    ----
done

until

until condition is false
do
    Commands for execution
    ----
done

ファイル・ディレクトリ操作

$ fpath='/a/b/c.d.e'
 
# ファイル名を取り出す (拡張子あり)
$ fname_ext="${fpath##*/}"
$ echo $fname_ext
c.d.e
 
# ファイル名を取り出す (拡張子なし)
$ fname="${fname_ext%.*}"
$ echo $fname
c.d
 
# 拡張子を取り出す
$ fext="${fpath##*.}"
$ echo $fext
e
 
# ディレクトリを取り出す
$ fdir="${fpath%/*}"
$ echo $fdir
/a/b

日時操作

`date xxx `でかこんで実行する.

DATE=`date -d "$1" '+%s'`
フォーマットコマンド
yyyy/mm/dddate ’+%Y/%m/%d’
yyyy/mm/dd (Sun..Sat)date ’+%Y/%m/%d (%a)‘
yy/mm/dddate ’+%y/%m/%d’
yyyy-mm-dddate ’+%F’
mm/dd/yydate ’+%D’
hh:mm (24 時間制)date ’+%R’
hh:mm:ss (24 時間制)date ’+%T’
hh:mm:ss AM PM (12 時間制)date ’+%r’

temp ファイル作成

  • TEMP=$(mktemp /tmp/tempfile.XXXXXXXX) To create a temporary file
  • TEMPDIR=$(mktemp -d /tmp/tempdir.XXXXXXXX) To create a temporary directory

String

  • ${string:0:1} のように書くと, 0-1 文字目を抜きだし.
  • ${#abc}のように書くと, 文字数を抜きだし.
  • [ string1 == string2 ] 文字列の比較.

Debug

  • set -x # turns on debugging
  • set +x # turns off debugging

入力待ち

read を利用する.

#!/bin/bash
while read KEY
do
    case $KEY in
        "boy" )
            echo Hey,boy!!
            break;;
        "girl" )
            echo Hey,girl!!
            break;;
        *)
            echo Typing boy or girl;;
    esac
done

🐟fish shell

昔の記事. もうこういう技術は時間が経つと風化するよね… blogには不向きな気がする, wikiに書いて更新したほうがいい.

ログインシェルをbashのままfishをつかう

ネットに転がってるスニペットはfishではなくbashがほとんどなので, 起動の途中まではbashで, インタラクティブシェルの利用時のみfishにしたい.

以下を .bashrcの冒頭に書く.

# If not running interactively, don't do anything
case $- in
    *i*) exec fish;;
      *) return;;
esac

ref. ログインシェルは bash のまま fish を利用する - Qiita

bash exportのfishの書き方

よくわすれちゃう. ChatGPTに丸投げでもいいかも.

# bash
export PATH="/home/tsu-nera/.local/share/solana/install/active_release/bin:$PATH"
 
# fish
set -gx PATH "/home/tsu-nera/.local/share/solana/install/active_release/bin" $PATH

テキスト整形

🔧sed

文字列置換

$ find . -type f | xargs sed -i -e "s/url: \/archives\/=/url: \/archives\//g"

ヘッダの挿入

sed -i '1s/^/test\n/' filename
sed -i '1i\test' filename

wiki にヘッダを挿入する

find . -name "*.org" -exec sed -i '1i\#+OPTIONS: toc:nil' {} \;

find

-exec と xargs の違い

  • exec は各行にたいして処理が実施される.
  • args はすべての行にたいして処理が実施される.
find . -name "*.txt" -exec wc -l {} \;
find . -name "*.txt" | xargs wc -l

-type f でファイルのみ. ディレクトリ無視.

シェル芸

✅ログインシェルを変更する(chsh)

chsh コマンドを利用する. 覚え方はchenge shell.

$ chsh -s /usr/bin/fish

特殊文字削除

🔗References