Try   HackMD

リダイレクションの種類 - シェルもどきをgoで自作する #6

おさらい

これまで

シェルもどき「oreshell」を自作している。
現状のoreshellはリダイレクションを行うとエラーになるのでリダイレクションできるように修正する。

リダイレクションの種類

oreshellのリダイレクション対応にあたってリダイレクションについていろいろぐぐって調べてみると、自分の知らないリダイレクション機能がいくつかあった。

posixで定義しているシェルのリダイレクションの種類を以下に示す。(参考)
以下、commandはコマンド名、nはコマンドのファイルディスクリプタ番号を表す。

入力のリダイレクション

command [n]< filepath

ファイルの内容をコマンドの入力用ファイルディスクリプタnへリダイレクト。nを省略した場合は0(標準入力)を指定したとみなす。

出力のリダイレクション

command [n]> filepath

コマンドの出力用ファイルディスクリプタnからファイルへリダイレクト。nを省略した場合は1(標準出力)を指定したとみなす。

command [n]>| filepath

コマンドの出力用ファイルディスクリプタnからファイルへ上書き禁止状態であってもリダイレクト。nを省略した場合は1(標準出力)を指定したとみなす。

上書き禁止ってなんだ?とぐぐってみると、posixシェルは「set -C」でリダイレクションによるファイルの上書きを禁止できるらしい。(参考)

例:

$ echo "abc" > hoge
$ cat hoge
abc
$ set -C
$ echo "def" > hoge
-bash: hoge: cannot overwrite existing file
$ echo "def" >| hoge
def

なお、「set +C」で元の状態(上書き許可)に戻る。

追記出力のリダイレクション

command [n]>> filepath

コマンドの出力用ファイルディスクリプタnからファイルへ追記書き込みでリダイレクト。nを省略した場合は1(標準出力)を指定したとみなす。

ヒアドキュメント

command [n]<< 終端文字列

指定した終端文字列までの入力(開業も含む)をコマンドの入力用ファイルディスクリプタnへリダイレクト。nを省略した場合は0(標準入力)を指定したとみなす。

使用例:

$ cat << EOF
> aaa
> bbb
> EOF
aaa
bbb

リダイレクションでヒアドキュメントができるとは知らなかった。
「<<-」で先頭のタブ文字を無視してくれるらしい。シェルスクリプトで使うと便利だそうな。コマンドラインからやろうとすると特殊な入力が必要となる。(参考1 参考2)

ファイルディスクリプタの複製

command [n]<&[m]

コマンドの入力用ファイルディスクリプタnをファイルディスクリプタmとして複製する。nを省略した場合は0(標準入力)を指定したとみなす。

command [n]>&[m]

コマンドの出力用ファイルディスクリプタnをファイルディスクリプタmとして複製する。nを省略した場合は1(標準出力)を指定したとみなす。

ファイルディスクリプタの複製というより、ファイルディスクリプタの接続先をつなげ直すと考えるほうが正しいような気がする。
出力の複製は

$ command 1>/dev/null 2>&1

でよく見かける。
順番を間違えると期待通り動作しない。(参考)
入力の複製はどんな時に使うのだろう?

「<&-」「>&-」とするとファイルディスクリプタを閉じるらしいが使い方が良くわからない。。。
シェルスクリプトを書くときに使うのだろうか?(参考)

ファイルディスクリプタを読み書き両方用に開く

command [n]<>filename

コマンドのファイルディスクリプタnを読み書き両方用に開く。nを省略した場合は0(標準入力)を指定したとみなす。

これも使い方が良くわからない。。。
シェルスクリプトを書くときに使うのだろうか?(参考)

リダイレクションについてその他

リダイレクションは複数指定できる

command リダイレクション1 リダイレクション2 ... リダイレクションn

$ cat hoge.txt - < hage.txt > result.txt

コマンドの前方にもリダイレクションを指定できる

リダイレクション1 リダイレクション2 ... リダイレクションn command

参考

試してみる。

$ cat hoge.txt
hoge
$ < hoge.txt cat
hoge
$ < hoge.txt cat > hoge2.txt
$ cat hoge2.txt
hoge

今回対応するリダイレクションの構文

oreshellで上記すべてを対応することを考えると気が遠くなるので、とりあえずリダイレクションの種類は以下の2つだけを対応する。

command [n]< filepath
command [n]> filepath

また、
リダイレクションを複数指定できるようにする。
が、
リダイレクション指定の位置はコマンドの後方のみとする。

上記以外は現時点では対応しない。