シェルワンライナー160本ノック問題17
問題17 コマンドが使えないときのコピー
トラブルで cat や cp などの外部コマンドが一切使えなくなった状況で、 Bash のビルトインコマンドや機能だけで /etc/passwd を ~/a にコピーする問題だった。まったく思いつかなかった。
正解例は
while read ln ; do echo $ln ; done < /etc/passwd > ~/a
である。ファイル passwd から一行ずつ読み込んで echo で出力するという方法だった。ただこの方法だと行頭に空白がある場合に対応できないらしい。ちょっと実験してみることにする。
echo ' hoge' > test
で行頭に空白を入れたテキストファイルを作る。そして正解例のコマンドを実行する:
while read ln ; do echo $ln ; done < test > ~/testread
そうして testread を cat で出力させると確かに行頭の空白が消えていた。これは read の仕様な気がするので man で確かめてみる。
標準入力、 または -u オプションの引き数として指定されたファイル・ディスクリプター fd から 1 行を読み込み、最初の単語を最初の name に代入し、2 番目の単語を 2 番目の name に代入します。以降も同様です。 余った単語とそれらの間の区切り文字は、最後の name に代入されます。 name よりも標準入力から読み込んだ単語の方が少ない場合には、 余っている name には空文字列が値として代入されます。 IFS 中の文字が、行を単語に分割するために使われます。
おそらく空白が区切り文字と認識されてしまい、出力されないのだと思う。行頭の空白をちゃんと出力するには
echo "$(</etc/passwd)" > ~/a
とすればいい。区切り文字を認識する処理がないので空白がちゃんと出力される。