# リダイレクションの種類 - シェルもどきをgoで自作する #6 ## おさらい これまで - [シェルってなに?コマンドラインインタプリタってなに? - シェルもどきをgoで自作する#1](https://hackmd.io/@jyami/HJzohRn2D) - [コマンドと引数の分解、環境変数PATHから探索、外部コマンドと内部コマンド - シェルもどきをgoで自作する #2](https://hackmd.io/@jyami/HyeSkkThP) - [字句解析その1 - シェルもどきをgoで自作する #3](https://hackmd.io/@jyami/Hk3bWSMQO) - [字句解析その2 - シェルもどきをgoで自作する #4](https://hackmd.io/@jyami/S1BkltxQu) - [リダイレクションってなに? - シェルもどきをgoで自作する #5](https://hackmd.io/@jyami/S113NQx8u) シェルもどき「[oreshell](https://github.com/jyami/oreshell)」を自作している。 現状のoreshellはリダイレクションを行うとエラーになるのでリダイレクションできるように修正する。 ## リダイレクションの種類 oreshellのリダイレクション対応にあたってリダイレクションについていろいろぐぐって調べてみると、自分の知らないリダイレクション機能がいくつかあった。 posixで定義しているシェルのリダイレクションの種類を以下に示す。([参考](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_07)) 以下、commandはコマンド名、nはコマンドのファイルディスクリプタ番号を表す。 ### 入力のリダイレクション ``` command [n]< filepath ``` ファイルの内容をコマンドの入力用ファイルディスクリプタnへリダイレクト。nを省略した場合は0(標準入力)を指定したとみなす。 ### 出力のリダイレクション ``` command [n]> filepath ``` コマンドの出力用ファイルディスクリプタnからファイルへリダイレクト。nを省略した場合は1(標準出力)を指定したとみなす。 ``` command [n]>| filepath ``` コマンドの出力用ファイルディスクリプタnからファイルへ上書き禁止状態であってもリダイレクト。nを省略した場合は1(標準出力)を指定したとみなす。 上書き禁止ってなんだ?とぐぐってみると、posixシェルは「set -C」でリダイレクションによるファイルの上書きを禁止できるらしい。([参考](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#set)) 例: ``` $ 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](https://ja.wikipedia.org/wiki/%E3%83%92%E3%82%A2%E3%83%89%E3%82%AD%E3%83%A5%E3%83%A1%E3%83%B3%E3%83%88#Unix%E3%82%B7%E3%82%A7%E3%83%AB) [参考2](https://www.kushiro-ct.ac.jp/yanagawa/ex-2017/3-unix/03.html)) ### ファイルディスクリプタの複製 ``` command [n]<&[m] ``` コマンドの入力用ファイルディスクリプタnをファイルディスクリプタmとして複製する。nを省略した場合は0(標準入力)を指定したとみなす。 ``` command [n]>&[m] ``` コマンドの出力用ファイルディスクリプタnをファイルディスクリプタmとして複製する。nを省略した場合は1(標準出力)を指定したとみなす。 ファイルディスクリプタの複製というより、ファイルディスクリプタの接続先をつなげ直すと考えるほうが正しいような気がする。 出力の複製は ``` $ command 1>/dev/null 2>&1 ``` でよく見かける。 順番を間違えると期待通り動作しない。([参考](https://qiita.com/ryskiwt/items/69a9f095356e162c4016)) 入力の複製はどんな時に使うのだろう? 「<&-」「>&-」とするとファイルディスクリプタを閉じるらしいが使い方が良くわからない。。。 シェルスクリプトを書くときに使うのだろうか?([参考](https://tldp.org/LDP/abs/html/io-redirection.html)) ### ファイルディスクリプタを読み書き両方用に開く ``` command [n]<>filename ``` コマンドのファイルディスクリプタnを読み書き両方用に開く。nを省略した場合は0(標準入力)を指定したとみなす。 これも使い方が良くわからない。。。 シェルスクリプトを書くときに使うのだろうか?([参考](https://tldp.org/LDP/abs/html/io-redirection.html)) ## リダイレクションについてその他 ### リダイレクションは複数指定できる ``` command リダイレクション1 リダイレクション2 ... リダイレクションn ``` 例 ``` $ cat hoge.txt - < hage.txt > result.txt ``` ### コマンドの前方にもリダイレクションを指定できる ``` リダイレクション1 リダイレクション2 ... リダイレクションn command ``` [参考](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_10) 試してみる。 ``` $ 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 ``` また、 リダイレクションを複数指定できるようにする。 が、 リダイレクション指定の位置はコマンドの後方のみとする。 上記以外は現時点では対応しない。
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up