Girdi dosyası aranabildiği zaman (normal dosyadan okumak gibi) veya aranamayan (bir borudan okumak gibi), sed
(ve diğer standart programlar) farklı davranacaktır ( bu bağlantıdakiINPUT FILES
bölümü okuyun ).
Dokümandan alıntı:
Standart bir yardımcı program aranabilir bir giriş dosyasını okuduğunda ve dosya sonuna ulaşmadan önce hatasız bir şekilde sona erdiğinde, yardımcı program açık dosya tanımındaki dosya ofsetinin yardımcı program tarafından işlenen son bayttan hemen sonra düzgün bir şekilde konumlandırılmasını sağlamalıdır.
Yani içinde:
(sed '/y/ q'; echo aaa; cat) < test
sed
q
EOF'ye ulaşmadan önce uit komutunu uyguladı , böylece zzz
satır başında dosya ofseti bıraktı , böylece cat
kalan satırları yazdırmaya devam edebildi (GNU sed bazı durumlarda POSIX uyumlu değil, aşağıya bakın).
Ve doktordan devam:
Aranamayan dosyalar için, o dosya için açık dosya açıklamasında dosyanın konumu belirtilmemiş
Bu durumda, davranış belirtilmemiş. Çoğu standart araç, sed
girdiyi mümkün olduğu kadar tüketecektir. Bu geçmesi okumak yyy
hattı ve q
hiçbir şey bırakılır böylece, ofset dosyayı kurtarmak olmadan uit cat
.
GNU sed
standarda uygun değildir, sistemin stdio uygulamasına ve glibc versiyonuna bağlıdır:
$ (gsed '/y/ q'; echo aaa; cat) < test
xxx
yyy
aaa
Burada, Mac OSX 10.11.6, CEPH arka uçlu Openstack üzerinde çalıştırılan sanal makineler Centos 7.2 - glibc 2.17, Ubuntu 14.04 - glibc 2.19 elde edildi.
Bu sistemlerde, -u
standart davranışı elde etmek için seçeneği kullanabilirsiniz :
(gsed -u '/y/ q'; echo aaa; cat) </tmp/test
ve boru için:
$ cat test | (gsed -u '/y/ q'; echo aaa; cat)
xxx
yyy
aaa
zzz
bu korkunç verimsiz performansa yol açar, çünkü sed
her seferinde bir byte okumak zorundadır. Aşağıdakilerden bir kısmı çıktı strace
:
$ strace -fe read sh -c '{ sed -u "/y/q"; echo aaa; cat; } <test'
...
[pid 5248] read(3, "", 4096) = 0
[pid 5248] read(0, "x", 1) = 1
[pid 5248] read(0, "x", 1) = 1
[pid 5248] read(0, "x", 1) = 1
[pid 5248] read(0, "\n", 1) = 1
xxx
[pid 5248] read(0, "y", 1) = 1
[pid 5248] read(0, "y", 1) = 1
[pid 5248] read(0, "y", 1) = 1
[pid 5248] read(0, "\n", 1) = 1
yyy
...
cat
(alt kabukta), ilk durumda dosya tanımlayıcısını yeniden kullanabileceği, çünkü stdin gerçek bir dosyaya bağlı. İkinci durumda stdin, bir dosyadan değil gerçek bir dosyadan geliyor. Ayrıca(sed '/y/ q'; echo aaa; cat) < <(cat test)
yazdırmadığını unutmayınzzz
.