コマンドライン操作
シェル
-
shell
- ユーザーからのコマンドを受け付け、必要なプログラムを実行する
-
いっぱいある
-
Bourne Shell
sh
- UNIXで標準的
-
bash: Bourne Again SHell
bash
- 多くのLinuxディストリビューションの標準シェル
-
C shell
csh
- C言語に似たスクリプトを利用できる
-
tcsh
- C shellの改良版
- LinuxでCシェルといったらこれ
-
Kornシェル
ksh
- Bourneシェルを拡張したもの
-
zsh
- Kornシェル拡張
- bashやtcshの機能を取り入れた
-
- 利用可能なもの一覧
cat /etc/shells
# /etc/shells: valid login shells
/bin/sh
/bin/dash
/bin/bash
/bin/rbash
-
【補】
- Ubuntuの
sh
はdash
らしい - dash: Debian Almquist shell
- Ubuntuの
-
【補】
- 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\$
シェルの基本操作と設定
補完機能
- Tab押すと入力補完されるやつ
カーソルの移動
- emacsとだいたい同じ
コマンドラインの編集
- C-d 前方削除
- C-h 後方削除
実行制御
- シグナル送る連中の一覧
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ユーザーのホームディレクトリを指す/home/wand
-
~/wand
と混同しないように/home/<現在のユーザ>/wand
シェル変数と環境変数
シェル変数
-
シェルが保持する状態
- ホームディレクトリ
- ログイン名
- 直前のコマンド
- シェルを終了すると失われる
- 別のシェルから参照することはできない
-
シェルが実行したプログラムから参照することはできない
- echosample.sh
echo $hoge
- シェル変数
hoge
を定義して呼び出してみる
hoge=1
./echosample.sh
- これは表示される
hoge=2 ./echosample.sh
2
- これも大丈夫
hoge=3 bash echosample.sh
3
-
逆に、シェルスクの中=子プロセスで定義した変数も持ち出せない
-
varsample.sh
piyo=1 echo $piyo
-
piyo=0
echo $piyo
./varsample.sh
echo $piyo
0
1
0
環境変数
- シェルで実行されるプログラムにも引き継がれる
hoge=3
export hoge
./echosample.sh
3
-
子プロセスの環境変数は親に持ち出されない
-
exportsample.sh
fuga=1 echo $fuga
-
export fuga
```sh
fuga=0
echo $fuga
./exportsample.sh
echo $fuga
0
1
0
主な環境変数
- PATH
-
PWD
- カレントディレクトリ
PS1
の\w
に入るディレクトリ- いたずらしなければ
pwd
とecho $PWD
は同じ
-
HOSTNAME
- ホスト名
PS1
の\h
-
USER
- 現在のユーザー
-
LOGNAME
- ログインシェルのユーザー名
-
PS1
- プロンプトの表示文字列
${debian_chroot:+($debian_chroot)}\u@\h:\w\$
-
PS2
- 複数行用
>
-
HISTSIZE
- コマンド履歴の最大値
1000
-
HISTFILE
- コマンド履歴を格納するファイル
/home/wand/.bash_history
-
HISTFILESIZE
- HISTFILEに保存する履歴数
2000
-
TERM
- 端末の種類
- emacs上のshellだと
dumb
とか xterm-256color
-
LANG
- ロケール
ja_JP.UTF-8
-
HOME
- カレントユーザーのホームディレクトリ
/home/wand
端末とは
-
昔はキーボードとディスプレイのセットを複数コンピュータに繋いでた
-
入出力特特化の機器: 「端末」
- 物理的
- 複数ユーザーが同時に利用できる
-
-
今「端末」と言われているのは仮想的なもの
-
有名どころ
- GNOME-terminal
- Konsole
- TeraTerm
-
-
コンソール
- 端末のうち、コンピュータ本体に直接接続して管理に利用するもの
-
「カーソルを1文字戻す」「画面クリア」などは特殊コード(エスケープシーケンス)
- 端末のメーカー依存
- 違いを吸収するために、termcapというデータベースが生まれた
- termcapを利用するにあたり、端末を識別する必要があるためTERM環境変数がある
環境変数PATH
-
コマンドには2種類ある
-
内部コマンド
- シェル自体に組み込まれているもの
-
外部コマンド
- 独立したプログラムとして存在するもの
- どこにあるの? … 環境変数
PATH
から探す -
PATHが通っていない場合は、絶対/相対パス指定しないといけない
- 相対パスの場合も
./hoge.sh
のように指定する
- 相対パスの場合も
-
- PATHの通し方
export PATH=$PATH:/additional/path
-
既存のパスの後ろに
:
区切りで追加する-
【補】前に割り込むと脆弱性になるのでNG
- 先頭から探し、見つかり次第打ち切る
-
コマンドの実行
複数実行
- 単なる逐次実行
pwd;ls
- エラーが出たら打ち切る
ls /piyo && pwd
/piyo
なんてないのでエラーが出るpwd
が実行されない
ls: '/piyo' にアクセスできません: そのようなファイルやディレクトリはありません
- どれか1つだけ実行
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
コマンドで表示可能- シェルの内部コマンドについては
--help
を使う
- シェルの内部コマンドについては
使用法: man [OPTION...] [SECTION] PAGE...
- マニュアルを構成するファイルは
/usr/share/man
にある -
MANPATH
環境変数で指定された場所を検索する-
指定なき場合、下記ファイルで定義される場所
/etc/man.config
/etc/man.conf
-
/etc/manpath.config
- ubuntuはこれだった
-
/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っぽい感じ
- テキストを1画面ずつ表示する
-
-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
- こちらもwhatisデータベースを使用する
-w
- オンラインマニュアルページの置き場を表示する
man -w crontab
/usr/share/man/man1/crontab.1.gz
ファイル操作コマンド
ls
-
-A, --almost-all
.
,..
以外all
-
-d, --directory
- ディレクトリの中身ではなく、ディレクトリ自身の情報を表示
- でもファイルにも使用できる
-
-F, --classify
-l
併用しない場合で、種類表示
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
-
iノード番号表示
- 104範囲あたりで
-
-
-t
- 日付順
- cf. 普段は辞書順
-
-h
,--human-readable
-
単位表示
- ファイルサイズ
-
cp
-
-f
,--force
- 強制上書き
-
-i
,--interactive
- 対話型で上書き確認
-
-p
--preserve=mode,ownership,timestamps
と同様- アクセス権、所有者・所有グループ、タイムスタンプを保護
-
--preserve[=ATTR_LIST]
-
指定した属性を保護
- デフォルト
mode,ownership,timestamps
-
追加可能属性
context
links
xattr
all
- デフォルト
-
-
-r
,-R
,--recursive
-
再帰的にコピー
- ディレクトリコピーで必須
-r
と-R
が同じって珍しい気がする
-
-
-d
--no-dereference --preserve=links
と同義
-
-P
,--no-dereference
- sourceのシンボリックリンクを辿らない
-
-a
,--archive
-dR --preserve=all
と同様- sourceのシンボリックリンクをたどらず、再帰的にコピーし、その際すべてを保護
- 要するに、できる限りコピー元の構成と属性をコピー先でも保存する
mv
-
cp
と同じオプション-f
-i
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
と異なり、エイリアスかどうか、等は教えてくれない
メタキャラクタの利用
種類
-
*
- 0文字以上の任意の文字列
-
?
- 任意の1文字
-
[]
- 列挙されている文字のうちいずれかの1文字
[0-9]
のようにすると、[0123456789]
の意-
-
自体を列挙するすべはない?[\-]
とかやっても駄目
-
[!]
- 列挙されている文字のいずれにもマッチしない任意の1文字
-
{}
- ブレース展開ってやつか
,
区切りの文字列にマッチ- 文字列の生成にも使える
パイプとリダイレクト
標準入出力
-
ストリーム
- データの入出力に伴うデータの流れ
- ディスプレイ出力、キーボード入力等すべてがこれに抽象化されている
- ストリームとしての基本的なインタフェース
番号(ファイルディスクリプタ) | 入出力名 | デフォルト |
---|---|---|
0 | 標準入力 | キーボード |
1 | 標準出力 | 画面(端末) |
2 | 標準エラー出力 | 画面(端末) |
-
ファイルディスクリプタ
- プログラムがアクセスするファイルやstdin/out/errをOSが識別するためのもの
-
ファイルオープン時は3以降が割り当てられる
- 0-2が上記の標準入出力で使用されるから
パイプ
- 標準出力を標準入力につなぐやつ
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
- ls_log
-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とかでよく見るやつ
- RUNでやってることを可視化
-
-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