LPIC あずき本v5.0 ch7 シェルとシェルスクリプト
シェル環境のカスタマイズ
環境変数とシェル変数
- 環境変数
- シェル自身と、そのシェルから起動されるすべてのプロセスに引き継がれる
- 代表
- PATH
- HOME
- シェル変数
- そのシェル内でのみ有効
export
- シェル変数を環境変数に
env
,printenv
- 環境変数を表示
CLUTTER_IM_MODULE=xim LS_COLORS= LESSCLOSE=/usr/bin/lesspipe %s %s XDG_MENU_PREFIX=gnome- LANG=ja_JP.UTF-8 ...
- オプションがない場合、
env
とprintenv
に違いはない
env > env printenv > printenv diff env printenv
55c55 < _=/usr/bin/env --- > _=/usr/bin/printenv
printenv
では、環境変数名を指定すると、それのみ表示する
printenv HOME
/home/wand
env HOME
env: `HOME': そのようなファイルやディレクトリはありません
set
- シェル変数と環境変数を表示
BASH=/bin/bash BASHOPTS=checkwinsize:cmdhist:complete_fullquote:expand_aliases:extglob:extquote:force_fignore:gnu_errfmt:histappend:interactive_comments:progcomp:promptvars:sourcepath ... __expand_tilde_by_ref () { if [[ ${!1} == \~* ]]; then eval $1=$(printf ~%q "${!1#\~}"); fi } ...
- シェル変数と関数とに区別はない
シェルのオプション
set
コマンドで各種オプションを確認・オン/オフ
set --help
Set or unset values of shell options and positional parameters. Change the value of shell attributes and positional parameters, or display the names and values of shell variables. Options: ... -o option-name Set the variable corresponding to option-name: allexport same as -a braceexpand same as -B emacs use an emacs-style line editing interface ... Using + rather than - causes these flags to be turned off.
- 一覧
set -o
allexport off braceexpand on emacs off errexit off errtrace off functrace off hashall on histexpand on history on ignoreeof off interactive-comments on keyword off monitor on noclobber off noexec off noglob off nolog off notify off nounset off onecmd off physical off pipefail off posix off privileged off verbose off vi off xtrace off
- おもなやつ
オプション | shorthand | 説明 |
---|---|---|
allexport | -a | 作成・変更した変数を自動的にエクスポートする |
emacs | emacs風のキーバインドにする | |
ignoreeof | Ctrl + Dによってログアウトしないようにする | |
noclobber | -C | 出力リダイレクトによる上書きを禁止する |
noglob | -f | メタキャラクタを使ったファイル名展開(file name generation)を無効にする |
vi | vi風のキーバインドにする |
-o allexport
, -a
-a Mark variables which are modified or created for export.
- 有効にしてみる
set -a set -o
- allexport off + allexport on braceexpand on emacs off ...
- シェル変数作ってみる
HOGE=3 printenv HOGE
3
- allexport無効化する
-o
の逆、+o
set +o allexport set -o
- allexport on + allexport off braceexpand on emacs off ...
- 既にexport済のものは更新される
HOGE=5 printenv HOGE
5
- 新しく作ったシェル変数はexportされない
PIYO=3 printenv PIYO
エイリアス
alias envless='env | less' envless
CLUTTER_IM_MODULE=xim LS_COLORS= HOGE=5 ...
- けす
unalias envless
envless
envless: コマンドが見つかりません
- もとの名前を隠すこともできる
alias ls='ls -l' ls
合計 84 -rw-r--r-- 1 wand docker 1649 4月 9 19:52 env -rw-r--r-- 1 wand docker 1654 4月 9 19:52 printenv -rw-r--r-- 1 wand docker 77047 4月 9 19:54 set
- もとの名前を呼び出す
\ls
env printenv set
- 後始末
unalias ls
関数の定義
function
はオプショナル{
,}
の後/前はスペース必須- 1行スタイルではセミコロン必須
function echohoge(){ echo 'hoge'; } echopiyo() { echo 'piyo'; } echohoge echopiyo
hoge piyo
- これは駄目
echodame() { echo 'dame' }
- 複数行に分けて書く(対話型)
- シェルスクでももちろん可能
- この場合セミコロン不要
echomulline() > { > echo 'a' > echo 'b' > echo 'c' > } echomulline
a b c
{
は()
と同じ行でもいい- セミコロンはあってもいい
mul() { echo 'a'; }
- 定義見る
declare -f echohoge
- 複数行スタイルに展開されている
echohoge () { echo 'hoge' }
- けす
- シェル変数とおなじ
unset echohoge echohoge
- 関数一覧みる
declare -F
... declare -f echopiyo declare -f hogehoge ...
- コマンド展開すると定義も見れる
$(declare -F | grep hoge)
echohoge () { echo 'hoge' } hogehoge () { echo 'hoge' }
bashの設定ファイル
ファイル | 説明 |
---|---|
/etc/profile |
ログイン時に実行 |
/etc/bash.bashrc |
bash起動時に実行される |
/etc/bashrc |
~/.bashrc から参照 |
~/.bash_profile |
ログイン時に実行 |
~/.bash_login |
~/.bash_profile がない場合、ログイン時に実行 |
~/.profile |
~/.bash_profile も~/.bash_login もない場合、ログイン時に実行 |
~/.bashrc |
bash起動時に実行 |
~/.bash_logout |
ログアウト時に実行 |
/etc/
以下のやつは全ユーザーから参照~/
以下のやつは対応するユーザーからのみ参照
/etc/profile
ファイル, /etc/profile.d
ディレクトリ以下*.sh
ファイル
- 基本的な環境変数などが設定される
# /etc/profile: system-wide .profile file for the Bourne shell (sh(1)) # and Bourne compatible shells (bash(1), ksh(1), ash(1), ...). if [ "${PS1-}" ]; then if [ "${BASH-}" ] && [ "$BASH" != "/bin/sh" ]; then # The file bash.bashrc already sets the default PS1. # PS1='\h:\w\$ ' if [ -f /etc/bash.bashrc ]; then . /etc/bash.bashrc fi else if [ "`id -u`" -eq 0 ]; then PS1='# ' else PS1='$ ' fi fi fi if [ -d /etc/profile.d ]; then for i in /etc/profile.d/*.sh; do if [ -r $i ]; then . $i fi done unset i fi
/etc/bash.bashrc
ファイル
- ディストリによっては無いらしい
- Ubuntu18.04にはあった
- rc: run commandsの意
- 全ユーザーから参照
~/.bash_profile
, ~/.bash_login
, ~/.profile
ファイル
- なかった
- ユーザごとの環境変数の設定等を行うのでしょう
PATH
とか
~/.bashrc
ファイル
- 対話型シェルが起動されるたびに実行される
- このシェルスクから
/etc/bashrc
を呼び出す- 全ユーザ用設定
~/.bash_logout
ファイル
- ログインシェル終了時に実行
-bash
のように、頭に-
がつく
bash起動時における設定ファイルの実行順序
- 暇な時に絵を書く
シェルスクリプト
シェルスクリプトの基礎
echo 'echo hoge' > hoge.sh bash hoge.sh source hoge.sh . hoge.sh
hoge hoge hoge
- ファイルパス指定で実行も出来る
- パスが通っていない場合、カレントにあっても
./
が必要 - 実行権を付与してあること
- パスが通っていない場合、カレントにあっても
hoge.sh ./hoge.sh chmod +x hoge.sh ./hoge.sh
hoge.sh: コマンドが見つかりません bash: ./hoge.sh: 許可がありません hoge
ps PID TTY TIME CMD 19989 pts/1 00:00:00 bash 21693 pts/1 00:00:00 ps sh ps PID TTY TIME CMD 19989 pts/1 00:00:00 bash 21726 pts/1 00:00:00 sh 21727 pts/1 00:00:00 ps exit
exec
する例
exec sh ps PID TTY TIME CMD 19989 pts/1 00:00:00 sh 21733 pts/1 00:00:00 ps exec bash # exitじゃない
- X Window Systemでウィンドウマネージャを起動するような場合、待機しているシェルのプロセスは不要なので
exec
してXのプロセスにすげ替えるべき
スクリプトに渡す引数
$1 ... ${n}
- シェルスクに渡すパラメータ
$#
- パラメータ数(
$1 ... ${n}
に対するn
)
- パラメータ数(
$@
- 全パラメータ(空白区切り)
$*
- 全パラメータ(環境変数IFSで指定されたもの)
実行結果の戻り値
$?
- 終了コード
hoge echo $? echo $?
Command 'hoge' not found 127 0
- コマンドが見つからない: exit 127
- echo 127: exit 0
ファイルのチェック
test
コマンド[]
記法
if [ -f ~/.bash_aliases ]; then . ~/.bash_aliases fi
if test -f ~/.bash_aliases ; then
と同義
制御構造
条件分岐
if-then-elif-else-fi
case
文による条件分岐
case-in-esac
month.sh
case $1 in 1) echo 'Jan' ;; 2) echo 'Feb' ;; *) echo 'others' ;; esac
. month.sh 1 . month.sh 2 . month.sh 3
Jan Feb others
for
文による繰り返し処理
- よくあるスクリプト言語のforeachにちかい
for.sh
for i in $(seq 1 10) do echo $i done
. for.sh
1 2 3 4 5 6 7 8 9 10
while
文による繰り返し処理
i=1 while test $i -le 10 do echo $i let i=i+1 done
read
コマンド
- 標準入力からの入力を受け付ける
list
hoge piyo fuga
echoes.sh
while read INPUT do echo $INPUT done
. echoes.sh < list
hoge piyo fuga
- こういう書き方もできる
while read INPUT do echo $INPUT done < $1
- この場合、使い方はこう
. echoes.sh list
シェルスクリプトの実行環境
- シバン
#!/bin/bash
- bash特有の機能を使っているのに
#!/bin/sh
とかかいちゃだめ - CRLF改行に気をつける
/bin/bash^M
になって死ぬ- windows環境でdockerを使うとよくある
- シェルスクの中で
export
しても、シェルスク呼び出し元のシェルに環境変数は持ち出されない - 実行したユーザの権限で動作する
- SUID, SGIDはバイナリにしか効かない。スクリプトファイルにつけても無視される
- shとかplとか
- セキュリティ上の理由らしい
- SUID, SGIDはバイナリにしか効かない。スクリプトファイルにつけても無視される
-rwsr-xr-x 1 root root 11 4月 9 21:42 root.sh
echo $USER
sudo ./root.sh ./root.sh
- SUIDが無視される
root wand