シェル
- shell
- ユーザーからのコマンドを受け付け、必要なプログラムを実行する
- いっぱいある
- 利用可能なもの一覧
cat /etc/shells
# /etc/shells: valid login shells
/bin/sh
/bin/dash
/bin/bash
/bin/rbash
- 【補】
- 【補】
- rbash
- restricted bashかな?
- あるユーザーに対し、実行可能なコマンドを絞りたいときに使う
- ログインシェルは
/etc/passwd
で定義されている
cat /etc/passwd | grep wand
wand:x:1000:999:wand,,,:/home/wand:/bin/bash
$
とか#
とか
$
: 一般ユーザー
#
: スーパーユーザー(root)
- 環境変数
PS1
で変えられる
echo $PS1
${debian_chroot:+($debian_chroot)}\u@\h:\w\$
シェルの基本操作と設定
補完機能
カーソルの移動
実行制御
stty -a
speed 38400 baud; rows 15; columns 78; line = 0;
intr = ^C; quit = ^\; erase = <undef>; kill = <undef>; eof = ^D; eol = <undef>;
eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
werase = ^W; lnext = ^V; discard = ^O; min = 1; time = 0;
-parenb -parodd -cmspar cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff
-iuclc -ixany -imaxbel -iutf8
opost -olcuc -ocrnl -onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0
ff0
isig icanon iexten -echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
echoctl echoke -flusho -extproc
- C-c
- キーボード割り込み
- SIGINT送る(Terminal Interrupt)
- C-z
- 一時停止
- SIGTSTP(Terminal Stop)
- C-l
- C-s
- C-q
- メタキャラクタ
~wand
とするとwandユーザーのホームディレクトリを指す
~/wand
と混同しないように
シェル変数
- シェルが保持する状態
- シェルを終了すると失われる
- 別のシェルから参照することはできない
- シェルが実行したプログラムから参照することはできない
echo $hoge
hoge=1
./echosample.sh
hoge=2 ./echosample.sh
2
hoge=3 bash echosample.sh
3
- 逆に、シェルスクの中=子プロセスで定義した変数も持ち出せない
piyo=1
echo $piyo
piyo=0
echo $piyo
./varsample.sh
echo $piyo
0
1
0
hoge=3
export hoge
./echosample.sh
3
fuga=1
echo $fuga
export fuga
fuga=0
echo $fuga
./exportsample.sh
echo $fuga
0
1
0
- PATH
- PWD
- カレントディレクトリ
PS1
の\w
に入るディレクトリ
- いたずらしなければ
pwd
とecho $PWD
は同じ
- HOSTNAME
- USER
- LOGNAME
- PS1
- プロンプトの表示文字列
${debian_chroot:+($debian_chroot)}\u@\h:\w\$
- PS2
- HISTSIZE
- HISTFILE
- コマンド履歴を格納するファイル
/home/wand/.bash_history
- HISTFILESIZE
- TERM
- 端末の種類
- emacs上のshellだと
dumb
とか
xterm-256color
- LANG
- HOME
- カレントユーザーのホームディレクトリ
/home/wand
端末とは
- 昔はキーボードとディスプレイのセットを複数コンピュータに繋いでた
- 入出力特特化の機器: 「端末」
- 複数ユーザーが同時に利用できる
- 今「端末」と言われているのは仮想的なもの
- コンソール
- 端末のうち、コンピュータ本体に直接接続して管理に利用するもの
- 「カーソルを1文字戻す」「画面クリア」などは特殊コード(エスケープシーケンス)
- 端末のメーカー依存
- 違いを吸収するために、termcapというデータベースが生まれた
- termcapを利用するにあたり、端末を識別する必要があるためTERM環境変数がある
- コマンドには2種類ある
- 内部コマンド
- 外部コマンド
- 独立したプログラムとして存在するもの
- どこにあるの? ... 環境変数
PATH
から探す
- PATHが通っていない場合は、絶対/相対パス指定しないといけない
- 相対パスの場合も
./hoge.sh
のように指定する
- PATHの通し方
export PATH=$PATH:/additional/path
コマンドの実行
複数実行
pwd;ls
ls /piyo && pwd
/piyo
なんてないのでエラーが出る
pwd
が実行されない
ls: '/piyo' にアクセスできません: そのようなファイルやディレクトリはありません
ls /piyo || pwd || date
ls /piyo
は失敗するので次へ
pwd
は成功する
pwd
が成功したのでdate
は実行されない
ls: '/piyo' にアクセスできません: そのようなファイルやディレクトリはありません
/home/wand/Desktop/learn/lpic
(date; pwd; ls) > result.log
- 現在のシェル内で実行
- ブレース前後のスペース必須
- cf.
ls {hoge,piyo,fuga}
はスペースがあってはならない
- こいつはそもそも「メタキャラクタ」であり分類が異なる
||
とか&&
とか効かない
{ date; pwd; }
引用符
''
""
$...
や${...}
が変数として展開される
$
そのものを出力したい場合はecho "\$"
``
echo "カレントディレクトリは`pwd`"
カレントディレクトリは/home/wand/Desktop/learn/lpic
echo "カレントディレクトリは$(pwd)"
コマンド履歴
- 上下またはC-p, C-nで履歴走査
history
コマンドで順に表示
- bashの履歴機能
!<履歴番号>
history
コマンドの番号で履歴指定し再実行
!-2
とかやると2つ前のやつ
!!
!<文字列>
!?<文字列>
マニュアルの参照
- オンラインマニュアルページ(manページ)
man
コマンドで表示可能
使用法: man [OPTION...] [SECTION] PAGE...
- マニュアルを構成するファイルは
/usr/share/man
にある
MANPATH
環境変数で指定された場所を検索する
- 指定なき場合、下記ファイルで定義される場所
/etc/man.config
/etc/man.conf
/etc/manpath.config
/etc/manpath.config
...
#MANDATORY_MANPATH /usr/src/pvm3/man
#
MANDATORY_MANPATH /usr/man
MANDATORY_MANPATH /usr/share/man
MANDATORY_MANPATH /usr/local/share/man
#---------------------------------------------------------
# set up PATH to MANPATH mapping
# ie. what man tree holds man pages for what binary directory.
...
- 出力結果が膨大なので、ページャが使用される
- 通常、
less
- テキストを1画面ずつ表示する
more
の高機能版
- キーバインドはviっぽい感じ
-P, --pager=
オプションで変更可能
man -p cat which
とかやるとドバっと出る
manのセクション
- 「
/etc/passwd
のオンラインマニュアルページを見たいのに
pass
コマンドのものが出てしまう」といった現象の回避
- 同一の名前で異なる内容を扱えるようにする
man 5 passwd
PASSWD(5) File Formats Manual PASSWD(5)
名前
passwd - パスワードファイル
説明
passwd ファイルには各ユーザアカウントの様々な情報が記録されている。
書かれているのは次の通り。
ログイン名
暗号化されたパスワード (無いこともある)
...
passwd
コマンドはセクション1(ユーザーコマンド)
man 1 passwd
PASSWD(1) General Commands Manual PASSWD(1)
名前
passwd - ユーザパスワードを変更する
書式
passwd [-f|-s] [name]
passwd [-g] [-r|-R] group
passwd [-x max] [-n min] [-w warn] [-i inact] login
passwd {-l|-u|-d|-S|-e} login
説明
passwd はユーザアカウント・グループアカウントのパスワードを変更す
...
man man
...
次の表はマニュアルの section 番号およびその section に含まれるページの
種類を示します。
1 実行プログラムまたはシェルコマンド
2 システムコール (カーネルが提供する関数)
3 ライブラリー呼び出し (プログラムライブラリーに含まれる関数)
4 Special files (usually found in /dev)
5 ファイルの書式と慣習 (例: /etc/passwd)
6 ゲーム
7 Miscellaneous (including macro packages and conventions), e.g.
man(7), groff(7)
8 システム管理コマンド (通常は root 用)
9 カーネルルーチン [非標準]
manコマンドの主なオプション
-a
-f
man -f crontab
whatis crontab
crontab (5) - tables for driving cron
crontab (1) - maintain crontab files for individual users (Vixie ...
- キーワード検索はwhatisデータベースを用いて行われる
makewhatis
コマンド...whatisデータベースの作成
mandb
により取って代わられた。たぶん
-k
man -k crontab
apropos crontab
anacrontab (5) - configuration file for anacron
crontab (1) - maintain crontab files for individual users (Vixie...
crontab (5) - tables for driving cron
-w
man -w crontab
/usr/share/man/man1/crontab.1.gz
ファイル操作コマンド
ls
-A, --almost-all
-d, --directory
-F, --classify
ls -aF ~
./ .cache/ .local/ Documents/
../ .cinnamon/ .mozc/ Downloads/
.ICEauthority .config/ .mozilla/ Music/
.Xauthority .dbus/ .profile Pictures/
.Xdefaults .emacs.d@ .ssh/ Public/
.ac-php/ .gconf/ .sudo_as_admin_successful Templates/
.bash_history .gitconfig .themes/ Videos/
.bash_logout .gnupg/ .wget-hsts dotfiles/
.bashrc .icons/ Desktop/ examples.desktop
-i
, --inode
-t
-h
, --human-readable
cp
-f
, --force
-i
, --interactive
-p
--preserve=mode,ownership,timestamps
と同様
- アクセス権、所有者・所有グループ、タイムスタンプを保護
--preserve[=ATTR_LIST]
- 指定した属性を保護
- デフォルト
mode,ownership,timestamps
- 追加可能属性
-r
, -R
, --recursive
- 再帰的にコピー
-r
と-R
が同じって珍しい気がする
-d
--no-dereference --preserve=links
と同義
-P
, --no-dereference
-a
, --archive
-dR --preserve=all
と同様
- sourceのシンボリックリンクをたどらず、再帰的にコピーし、その際すべてを保護
- 要するに、できる限りコピー元の構成と属性をコピー先でも保存する
mv
mkdir
-m
, --mode=MODE
-p
, --parents
- 親ディレクトリも作る
mkdir -p /hoge/piyo/fuga
とかやるとhoge,piyoも作られる
- cf.
-p
がないと「No such file or directory」と怒られる
rm
-f
-i
-r
, -R
, --recursize
- ディレクトリを中のファイルごと消すときはこいつ
rmdir
- 空のディレクトリを消す
-p
, --parents
touch
- 「触る」...もともとタイムスタンプを更新するやつ
- タイムスタンプ
-a
アクセス時刻のみ更新
-m
更新時刻のみ更新
-t
タイムスタンプの指定
file
- テキストなのかバイナリなのか、文字コードは何なのか等を事前調査
file /etc/hosts
/etc/hosts: ASCII text
file /dev/sda
/dev/sda: block special (8/0)
file /proc/scsi/scsi
/proc/scsi/scsi: empty
【Ver5.0】type
type {echo,which,sh,bash,ls}
echo はシェル組み込み関数です
which はハッシュされています (/usr/bin/which)
sh はハッシュされています (/bin/sh)
bash は /bin/bash です
ls は `ls --color=auto' のエイリアスです
【Ver5.0】which
which ls
/bin/ls
type
と異なり、エイリアスかどうか、等は教えてくれない
メタキャラクタの利用
種類
*
?
[]
- 列挙されている文字のうちいずれかの1文字
[0-9]
のようにすると、[0123456789]
の意
-
自体を列挙するすべはない?
[!]
- 列挙されている文字のいずれにもマッチしない任意の1文字
{}
- ブレース展開ってやつか
,
区切りの文字列にマッチ
- 文字列の生成にも使える
パイプとリダイレクト
標準入出力
- ストリーム
- データの入出力に伴うデータの流れ
- ディスプレイ出力、キーボード入力等すべてがこれに抽象化されている
- ストリームとしての基本的なインタフェース
番号(ファイルディスクリプタ) |
入出力名 |
デフォルト |
0 |
標準入力 |
キーボード |
1 |
標準出力 |
画面(端末) |
2 |
標準エラー出力 |
画面(端末) |
- ファイルディスクリプタ
- プログラムがアクセスするファイルやstdin/out/errをOSが識別するためのもの
- ファイルオープン時は3以降が割り当てられる
パイプ
ls
anaconda-post.log bin dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
ls | wc -l
- lsの標準出力ををwc (word count)の標準入力へ
- 行数を数え、ファイル数を得る
19
journalctl -k | less
tee
- 標準入力を「T字に」フォーク
- 引数(ファイル名)を省略すると、単に標準出力のみ行う
ls -l | tee ls_log | wc -l
20
-rw-r--r-- 1 root root 12076 Dec 5 01:37 anaconda-post.log
lrwxrwxrwx 1 root root 7 Dec 5 01:36 bin -> usr/bin
drwxr-xr-x 5 root root 360 Feb 25 02:56 dev
drwxr-xr-x 1 root root 4096 Feb 25 02:56 etc
drwxr-xr-x 2 root root 4096 Apr 11 2018 home
lrwxrwxrwx 1 root root 7 Dec 5 01:36 lib -> usr/lib
lrwxrwxrwx 1 root root 9 Dec 5 01:36 lib64 -> usr/lib6
drwxr-xr-x 2 root root 4096 Apr 11 2018 media
drwxr-xr-x 2 root root 4096 Apr 11 2018 mnt
drwxr-xr-x 2 root root 4096 Apr 11 2018 opt
dr-xr-xr-x 174 root root 0 Feb 25 02:56 proc
dr-xr-x--- 1 root root 4096 Feb 25 03:02 root
drwxr-xr-x 11 root root 4096 Dec 5 01:37 run
lrwxrwxrwx 1 root root 8 Dec 5 01:36 sbin -> usr/sbin
drwxr-xr-x 2 root root 4096 Apr 11 2018 srv
dr-xr-xr-x 13 root root 0 Feb 25 02:56 sys
drwxrwxrwt 7 root root 4096 Dec 5 01:37 tmp
drwxr-xr-x 13 root root 4096 Dec 5 01:36 usr
drwxr-xr-x 18 root root 4096 Dec 5 01:36 var
- Dockerfileとかでよく見るやつ
-a
, --append
で、上書きではなく追記する
リダイレクト
> ファイル
< ファイル
>> ファイル
2> ファイル
2>> ファイル
> ファイル 2>&1
, &>
>> ファイル 2>&1
m>&n
の意味
m>&n
は「nと同じ出力先のmを作る」の意
- 複製にすぎないので、これの後にnが変わってもmは追従しない
sh test.sh > out.log 2>&1
sh test.sh > out.log
で、1の出力先がout.logになる
2>&1
で、2の出力先が1と同じ、すなわちout.logになる
- つまり、標準出力と標準エラー出力がout.logに書き出される
sh test.sh 2>&1 out.log
2>&1
で、2の出力先が1と同じ、すなわち標準出力になる
- 単にshの結果が標準出力されて終わる(おそらく意図しない挙動)
ヒアドキュメント
<< EOF
- 特定の文字列(この例では
EOF
)が現れるまで標準入力から入力
/dev/null
cat < /dev/null > ls_log
ls > /dev/null