シェルのリダイレクトでわりと使うやつをメモしておく。
シェルのリダイレクト
シェルスクリプトを書くときにわりと使うリダイレクトのやつを書いていく。
/bin/sh
のバージョン。普通に bash.
$ /bin/sh --version GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin19) Copyright (C) 2007 Free Software Foundation, Inc.
このへんは man sh
すると sh は /private/var/select/sh
のシンボリックリンクが実行すると書いてあるので /private/var/select/sh
を見たら /bin/bash
へのシンボリックリンクになってた。
/bin/sh
を実行すると /bin/bash
が sh 互換で動く感じ。
It is implemented by re-execing as either bash(1), dash(1), or zsh(1) as determined by the symbolic link located at /private/var/select/sh.
標準出力のリダイレクト
標準出力のリダレクトは >
を使う。
# 標準出力をファイルにリダイレクトする $ echo Hello > stdout.txt $ cat stdout.txt Hello
>
はリダイレクト先のファイルの中身を上書きする。
$ echo Hello > stdout.txt $ echo World > stdout.txt $ cat stdout.txt World
リダイレクト先のファイルを上書きじゃなくて追記するときは >>
を使う。
$ echo Hello > stdout.txt $ echo World >> stdout.txt $ cat stdout.txt Hello World
標準エラー出力のリダイレクト
標準エラー出力は >
でリダイレクトするけど >
は標準エラー出力はリダイレクトしない。
ls /hoge/not/exists
みたいに存在しないファイルを ls するとメッセージがプロンプトに表示するしリダイレクト先の stderr.txt
は空っぽになる。
$ ls /hoge/not/exists ls: /hoge/not/exists: No such file or directory $ cat stderr.txt
標準エラー出力のリダイレクトは 2>
を使う。
ls /hoge/not/exists
みたいに存在しないファイルを ls するとメッセージがプロンプトに表示されなくてちゃんとリダイレクト先の stderr.txt
に入る。
$ ls /hoge/not/exists 2> stderr.txt $ cat stderr.txt ls: /hoge/not/exists: No such file or directory
2>
はリダイレクト先のファイルを上書きする。リダイレクト先のファイルを上書きじゃなくて追記するときは 2>>
を使う。
$ ls /hoge/not/exists 2> stderr.txt $ ls /fuga/not/exists 2> stderr.txt $ cat stderr.txt ls: /fuga/not/exists: No such file or directory $ ls /hoge/not/exists 2> stderr.txt $ ls /fuga/not/exists 2>> stderr.txt $ cat stderr.txt ls: /hoge/not/exists: No such file or directory ls: /fuga/not/exists: No such file or directory
標準入力とかのリダイレクトで使うファイルディスクリプタ
標準エラーのリダイレクトで 2>
とか 2>>
みたいにしたときの 2
はファイルディスクリプタを指定してる。
標準出力とか標準エラー出力のファイルディスクリプタは一般的に以下のようになってるので 2>
は標準エラー出力をリダイレクトするという意味になる。
ファイルディスクリプタ | 対象 |
---|---|
0 | 標準入力 |
1 | 標準出力 |
2 | 標準エラー出力 |
あと標準出力のリダイレクトは >
とか >>
みたいに書いたけど標準出力のファイルディスクリプタは 1
なので 1>
とか 1>>
みたいにしても同じ動きになる。
$ echo Hello 1> stdout.txt $ echo World 1>> stdout.txt $ cat stdout.txt Hello World
標準入力のリダイレクト
標準入力のリダレクトは <
を使う。
$ cat stdout.txt Hello World $ grep Hello < stdout.txt Hello
ヒアドキュメント
標準入力はヒアドキュメント <<
をリダイレクトすることができる。
$ cat << EOF Hello World EOF Hello World $ grep Hello << EOF Hello World EOF Hello
標準出力をファイルにリダイレクトして空っぽのファイルを作る
ファイルを空っぽにするときに echo > stdout.txt
みたいにすると stdout.txt の内容は空っぽにならない。
$ echo > stdout.txt $ ls -l stdout.txt -rw-r--r-- 1 shrimp staff 1 7 24 14:48 stdout.txt $ od stdout.txt 0000000 000012 0000001
これ、bash なら echo -n > stdout.txt
でファイルを空っぽにできるけど sh で echo -n > stdout.txt
をやると -n
というファイルになっちゃう。
rm stdout.txt; touch stdout.txt
でファイルを削除してから空のファイルを作ってもいいけど :>
みたいにするほうが楽なので :>
を使うことが多い気がする。
$ :> stdout.txt $ ls -l stdout.txt -rw-r--r-- 1 shrimp staff 0 7 24 14:49 stdout.txt $ od stdout.txt
ちなみに ubuntu は /bin/sh
が dash のシンボリックリンクになってるんだけど echo -n > stdout.txt
で普通にファイルを空っぽに出来ると Twitter で教えてもらった。
docker container run --rm -it ubuntu /bin/sh
コマンドで ubuntu の Docker コンテナを起動していろいろ試してみたけどちゃんと echo -n > stdout.txt
でファイルを空っぽにできる……
# ls -l /bin/sh lrwxrwxrwx 1 root root 4 Aug 7 2019 /bin/sh -> dash # echo -n > stdout.txt # ls -l stdout.txt -rw-r--r-- 1 root root 0 Jul 24 10:31 stdout.txt # cat stdout.txt