一部のBourneに似たシェルでは、組み込みコマンドはファイルの行全体をread
読み取ることができません/proc
(次のコマンドはで実行する必要があり、zsh
他の$=shell
シェルに置き換える必要があります$shell
)。
$ for shell in bash dash ksh mksh yash zsh schily-sh heirloom-sh "busybox sh"; do
printf '[%s]\n' "$shell"
$=shell -c 'IFS= read x </proc/sys/fs/file-max; echo "$x"'
done
[bash]
602160
[dash]
6
[ksh]
602160
[mksh]
6
[yash]
6
[zsh]
6
[schily-sh]
602160
[heirloom-sh]
602160
[busybox sh]
6
read
標準では、標準入力がテキストファイルである必要があります。、この要件によって他の動作が発生しますか?
POSIX定義を読むテキストファイル、いくつかの確認を行いました。
$ od -t a </proc/sys/fs/file-max
0000000 6 0 2 1 6 0 nl
0000007
$ find /proc/sys/fs -type f -name 'file-max'
/proc/sys/fs/file-max
NUL
内容に文字がなく、/proc/sys/fs/file-max
一般find
ファイルとしても報告されます(これはのバグですかfind
?)。
私はシェルが次のように後ろから何かをしていると思いますfile
。
$ file /proc/sys/fs/file-max
/proc/sys/fs/file-max: empty
ベストアンサー1
問題は、/proc
Linuxでは、これらのファイルはstat()/fstat()
テキストファイルのように見えますが、それはうまくいかないということです。
動的データであるため、read()
そのデータに対して1つのシステムコールしか実行できません(少なくとも一部のデータについては)。複数の操作を実行すると、内容が異なる2つのチャンクが発生する可能性があるため、2番目の操作は何も返さないようですread()
(ファイルの終わりを意味します)(lseek()
最初に戻らない限り(そして先頭のみ))。
ユーティリティread
は一度に1バイトずつファイルの内容を読み、改行文字のみが読み取られるようにする必要があります。これはdash
:
$ strace -fe read dash -c 'read a < /proc/sys/fs/file-max'
read(0, "1", 1) = 1
read(0, "", 1) = 0
一部のシェルは、あまりにも多くのシステムコールをbash
実行しないように最適化するのが好きです。read()
まず、ファイルが検索可能であることを確認し、その場合はファイルを塊として読みます。すでにファイルを読んでいる場合は、カーソルを改行文字の後ろに戻すことができることを知っています。
$ strace -e lseek,read bash -c 'read a' < /proc/sys/fs/file-max
lseek(0, 0, SEEK_CUR) = 0
read(0, "1628689\n", 128) = 8
を使用すると、bash
128バイトを超え、単一の読み取りシステム呼び出しでのみ読み取ることができるprocファイルで問題が発生します。
bash
-d
このオプションを使用すると、この最適化も無効になっているように見えます。
ksh93
追加の最適化はさらに偽になります。 ksh93はread
逆追跡を実行しますが、nextのために読み取った追加のデータを記憶するので、read
next(またはread
などのデータを読み取る他の組み込み関数)は、異なるコマンド間でそのデータを試行しません(修正された場合でも)。 :cat
head
read
$ seq 10 > a; ksh -c 'read a; echo test > a; read b; echo "$a $b"' < a
1 2
$ seq 10 > a; sh -c 'read a; echo test > a; read b; echo "$a $b"' < a
1 st