スクリプトを読み取ると、シェルはファイル、パイプ、またはその他のソース(stdin?)からスクリプトを読み込みます。一部のコーナー条件では、入力が見つからない場合があります(ファイル位置を以前の位置に戻すことはできません)。
というread は、エスケープされていない改行文字が見つかるまで stdin を一度に 1 バイトずつ読み込みます。
シェルはスクリプト入力で一度に1文字ずつ読み取る必要がありますか?
使用できる追加のデータテキストファイルではなく、スクリプトを意味します。
それでは、なぜこれが必要ですか?いくつかの仕様で定義されていますか?
すべてのシェルが同様に動作しますか?どちらではないか?
ベストアンサー1
シェルはスクリプトファイルまたはデバイス記述子から読み取られます。
あるいは、パイプから取得できない入力fdを取得する最も簡単な方法です。
シェルはスクリプト入力で一度に1文字ずつ読み取る必要がありますか?
stdinから読み取るコマンドを実行するスクリプトをサポートし、スクリプト自体の行を使用して入力を取得したい場合。
このように:
$ cat foo.sh
#!/bin/sh
line | sed -e 's/^/* /'
xxx
echo "end."
$ cat foo.sh | bash
* xxx
end.
このline
コマンドは標準入力()から1行を読み込みxxx
、シェルは別の行をコマンドで読み込みます。これを行うには、あまりにも多くのline
入力を読み取らないように注意する必要があります。それ以外の場合、シェルに次の行は表示されません。 GNUユーティリティはあまりにもhead -n1
多くの量を読みます。たとえば、sed
util-linuxのユーティリティはline
一度に1バイトずつ読み取って、前の改行を読み取らないように注意します。
dash
上記のスクリプトは、スクリプト全体を一度に読み取るため機能しません。
$ cat foo.sh | dash
*
dash: 3: xxx: not found
end.
DashとBusyboxはブロック全体を読み取り、私がテストした他のもの(Bash、Ksh、mksh
Zsh)はバイト単位で読み取ります。
これはかなり複雑なスクリプトであり、たとえば、次のように実行すると正しく動作しません。bash foo.sh
これは、stdin
スクリプト自体を指すのではなく、その行がコマンドxxx
として扱われるためです。スクリプト自体にデータを含めるには、ここにあるドキュメントを使用する方が良いかもしれません。これはsh bar.sh
、sh < bar.sh
または次回実行するとすべてのシェルで機能しますcat bar.sh | sh
。
$ cat bar.sh
#!/bin/sh
sed -e 's/^/* /' <<EOF
xxx
EOF
echo "end."