Shell Script mktemp, geçici adlandırılmış yöneltme oluşturmak için en iyi yöntem nedir?


30

Geçici dosyalar oluşturmak için elinden gelenin en iyisini biliyorum mktemp, ama peki adlandırılmış yöneltmeler?

İşlerin mümkün olduğunca POSIX uyumlu olmasını tercih ediyorum, ancak Linux yalnızca kabul edilebilir. Bashizmlerden kaçınmak, yazdığım tek zor kriterlerim dash.

Yanıtlar:


41
tmppipe=$(mktemp -u)
mkfifo -m 600 "$tmppipe"

Mevcut bir dosya veya sembolik bir bağlantı tarafından ele geçirilmeye yatkın olan normal dosya oluşturma işleminin aksine, belirtilen ad mkfifoveya alt işlev aracılığıyla bir ad borusu oluşturulması ya da belirtilen yerde yeni bir dosya oluşturur veya başarısız olur. Gibi bir : >fooşey güvensiz çünkü eğer saldırgan çıktısını tahmin mktempedebilirse saldırgan kendisi için hedef dosyayı oluşturabilir. Ancak mkfifo fooböyle bir senaryoda başarısız olur.

Tam POSIX taşınabilirliğine ihtiyacınız varsa, mkfifo -m 600 /tmp/myfifokaçırılmaya karşı güvenli ancak hizmet reddine eğilimlidir; Güçlü bir rasgele dosya adı üretecine erişmeden, yeniden deneme girişimlerini yönetmeniz gerekir.

Geçici dosyalardaki ince güvenlik sorunlarıyla ilgilenmiyorsanız, basit bir kuralı uygulayabilirsiniz: özel bir dizin oluşturun ve her şeyi orada tutun.

tmpdir=
cleanup () {
  if [ -n "$tmpdir" ] ; then rm -rf "$tmpdir"; fi
  if [ -n "$1" ]; then kill -$1 $$; fi
}
tmpdir=$(mktemp -d)
trap 'cleanup' EXIT
trap 'cleanup HUP' HUP
trap 'cleanup TERM' TERM
trap 'cleanup INT' INT
mkfifo "$tmpdir/pipe"

Aslında bunu daha önce dünkü çözümüm olarak seçtim, birisinin göndermesini ya da daha iyi birisini görmek için bekliyordum. Ayrıca, benim durumumda dir'in gitmenin yolu olduğunu hissettim. Ne olursa olsun ... Yardımın için teşekkürler, minnettarım.
JM Becker

1
Trap komutu olmamalı trap "rm -rf '$tempdir'" EXIT HUP INT TERMmı? Tuzak kendi değişken genişlemesini yapabilir mi?
Altı

Artıracağı hakimiyetin @Six $tempdiranda trapkomut değerlendirilir anda tuzak tetiklenir değil. Bu durumda, değeri tempdirtek bir alıntı içeriyorsa, kodunuzun her zaman işe yaradığı durumlarda, kodunuzun korkunç şekilde kırılması dışında herhangi bir fark yaratmaz .
Gilles 'SO- kötülük'

@Gilles Bu hoş bir özellik. Tek alıntı örneğinizi şanssız denedim, bu yüzden tuzağın çalışma zamanında değişkenleri değerlendiremediğini düşündüm. $tempdirYerel olarak ilan edildiğimi ve tuzağın buna erişebilmesi için küresel olarak tanımlanması gerektiğini ortaya koydu . Şimdi mantıklı ...
Altı

1
@Gilles ... $tempdir değer değişmediği sürece , bu temelde tüm amaçlar için kabul edilebilir. Birden fazla geçici dosya / dizin oluşturmak için aynı adı kullanmamaya dikkat edin ...
MestreLion

3

Daha güvenli bir alternatif, güvenli mktempbir dizin oluşturmak için kullanmaktır , daha sonra adlandırılmış yönelticinizi bu dizinin içine koymak rm -R $dir, sonunda dizinden kurtulmak için yapmaktır .


mktempFIFO'yu bir dizinde oluşturmayı seçtim , çünkü gerçekten kabul edilebilir tek cevap buydu.
JM Becker,

2

"Kuru çalıştırma" seçeneğini kullanın:

mkfifo $(mktemp -ut pipe.XXX)

1
Man sayfalarına göre, -u"teşvik edilmez" seçeneğinin kullanılması .
dogbane

@dogbane Yani kullanımı -t, ama güvenilir bir şekilde çalıştığı sürece, onunla giderdim.
polemon

pardon, bunun -tcesareti kırıldığı söyleniyor ?
dogbane

2
@dogbane Herhangi bir şekilde kritik bir öneme sahipse , mkstemp()işlevi çağıran küçük bir C uygulaması yapardım ( linux.die.net/man/3/mkstemp ). -tAnahtar, öyle cesareti değil -p, benim hatam.
polemon

1

Kullanabilirsiniz mktempGeçici bir dosya oluşturmak için , sonra silin ve aynı isimli bir adlandırılmış kanal oluşturun.

Örneğin:

TMPPIPE=$(mktemp -t pipe.XXX) && {
    rm -f $TMPPIPE
    mkfifo $TMPPIPE
}

Silmeden mu $TMPPIPEönce mkfifokaçınmak yapmaktan ilişkili 'güvensiz' sorunu TMPPIPE=`mktemp -u` ; mkfifo $TMPPIPE?
JM Becker

1
@TechZilla mkfifo, kabuktan normal dosya oluşturmanın aksine, aslında güvenlidir. Olmazsa, bir dosya oluşturmak ve sonra onu silmek hiç yardımcı olmaz (aslında dosya adını tahmin etmesini istemeksizin saldırganın işini büyük ölçüde kolaylaştıracaktır). Dogbane'nin cevabı işe yarıyor ama ara dosya oluşturma işe yaramaz bir komplikasyon.
Gilles 'SO- kötülük' dur '24

1
@Gilles, mktempMan sayfasının hangi açıdan -u'güvensiz' diye adlandırıldığını biliyor musunuz ?
JM Becker

@ doogbane, cevabınıza oy verdim ve düşündüğüm yorumlarınız katıydı. Buna rağmen, dün bunu zaten bitirdim .. Birisi ya benim çözümümü ya da umarım daha iyi bir şey yayınladığında görmeyi bekliyordum. Bu yüzden kullanmış olmama rağmen mktemp -d, girişin için hala bazı puanların var. Yardımlarınız için teşekkürler, gerçekten minnettarım!
JM Becker

1
@TechZilla mktemp -unormal bir dosya oluştururken güvensizdir, çünkü hizmet reddine karşı koruma sağlar (ürettiği ad yeterince tahmin edilemezse) ancak saldırganın programın burnunun altında dosyayı oluşturmasını engellemez. Normal bir dosya yerine bir fifo oluşturmak, man sayfasının ele almadığı nadir bir kullanım durumudur.
Gilles 'SO- kötülük olmayı bırak'

0

İki ayrı işlemle boruya isme göre erişilebildiği Unix'te mkfifoya da kullanın mknod- bir işlem onu ​​bir okuyucu, diğeri bir yazar olarak açabilir.

mkfifo my_pipe
gzip -9 -c < my_pipe > out.gz
cat file > my_pipe

Belirtilen boru, herhangi bir dosya gibi silinebilir:

rm my_pipe

mkfifo --mode=0666 /tmp/namedPipe
gzip --stdout -d file.gz > /tmp/namedPipe

NamedPipe sadece bir kez okumak için normal bir dosya kullanılabilir.

http://www.linuxjournal.com/article/2156


2
İsimli boruların tamamen farkındayım mkfifo. Geçici olarak adlandırılmış yöneltmeler hakkındaki soruma değil , mkdirgeçici dizinler oluşturmaya değiniyor.
JM Becker

2
Bu mktemp, güvenli bir şekilde adlandırılmış yöneltme oluşturmayı hedefleyen sorunları nasıl çözer?
Camh

1
oh ok, / tmp altında onları oluşturmak en iyisidir, tanım gereği geçici dosyalardır ve sistem yeniden başlatıldığında silinir. Ya da daha iyisi, mktempsonucun kendisinden adlandırılmış boruyu yaratacak bir kabuk fonksiyonuna sahip (tabii ki önce temp dosyasını silerek ve sonra mkfifoaynı şekilde çalışarak ). mktempgeçici bir dizin oluşturmak için de kullanılabilir, -t -danahtarla deneyin .
Nikhil Mulley
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.