$$ kabukta ne anlama geliyor?


143

Bir keresinde temp dosyaları için bir kabuk benzersiz bir dosya adı elde etmenin bir yolu çift dolar işareti ( $$) kullanmak olduğunu okudum . Bu, zaman zaman değişen bir sayı üretir ... ancak tekrar tekrar çağırırsanız, aynı numarayı döndürür. (Çözüm sadece zamanı kullanmaktır.)

Gerçekte ne $$olduğunu ve neden benzersiz dosya adları oluşturmanın bir yolu olarak önerileceğini merak ediyorum .

Yanıtlar:


102

Bash'te $$işlem kimliği, yorumlarda belirtildiği gibi, çeşitli nedenlerle geçici dosya adı olarak kullanılması güvenli değildir.

Geçici dosya adları için mktempkomutu kullanın.


35
Sadece en üstteki cevaba bakanlar için, genel olarak yazılabilir bir dizine (ör. / Tmp) yazılırsa $$ tek bir dosya için bile iyi değildir. Komut dosyanızın istenmeyen bir yere yazmasına neden olacak sembollerle çöp / tmp yapmak kolaydır. mktemp çok daha iyi.
Chris Jester-Young

4
Evet, $$ kullanmak kötü bir güvenlik açığına neden olur. Yapma.
emk

7
Ya da soruyu soran kişi, aşağıdaki yüksek puanlı cevabı kabul edilen cevap olarak belirlemelidir ...
jtimberman

6
SEO için "dolar doları" ekliyorum.
Antoine

1
$$ sadece pid çıktısı verirse, nasıl "güvenli değil" olabilir? Güvenlik açığı, kötü tasarımın tmp dosya adında PID kullanmaması nedeniyle yaratılır ... tmp'ye giden çıkışın bütünlüğünü önemsiyorsanız, belki oraya ilk etapta koymamalısınız? $$ güvenlik
açığına

113

$$bash içindeki işlem kimliği (PID). Kullanmak $$kötü bir fikirdir, çünkü genellikle bir yarış durumu yaratır ve kabuk betiğinizin bir saldırgan tarafından altüst edilmesine izin verir. Örneğin, güvensiz geçici dosyalar oluşturan ve güvenlik önerileri vermek zorunda olan tüm bu kişilere bakın .

Bunun yerine kullanın mktemp. Mktemp ilişkin Linux sayfası mükemmel. İşte bazı örnek kod:

tempfoo=`basename $0`
TMPFILE=`mktemp -t ${tempfoo}` || exit 1
echo "program output" >> $TMPFILE

3
Teşekkürler. mktempSeçenek -tşimdi (ben çünkü karakter ile sorunlar düşünmek kullanımdan kaldırıldı -). Bu günleri kullanmktemp ${tempfoo}.XXXXXX . Gönderinizi güncelleme özgürlüğünü alıyorum.
Sebastian

1
Ayrıca unutmayın, lütfen backtick kullanımdan kaldırıldı , bu yüzden kullanmak TMPFILE=$(mktemp)yerine.
Michael Kopp


7

UNIX benzeri bir işletim sistemindeki her işlemin (geçici olarak) benzersiz bir tanımlayıcısı olan PID'si vardır. Aynı anda çalışan iki işlem aynı PID'ye sahip olamaz ve $$ betiği çalıştıran bash örneğinin PID'sini belirtir.

Bu, asla tekrar kullanılmayacağı anlamında benzersiz bir tanımlayıcı değildir (aslında PID'ler sürekli olarak yeniden kullanılır). Size verdiği şey bir sayıdır, böylelikle başka bir kişi betiğinizi çalıştırırsa, sizinkini çalıştırırken farklı bir tanımlayıcı alacaktır. Sizinki öldükten sonra PID geri dönüştürülebilir ve başka biri komut dosyanızı çalıştırabilir, aynı PID'yi alabilir ve aynı dosya adını alabilir.

Bu nedenle, "$$ bir dosya adı verir, böylece benim örneğim hala çalışıyorken başka bir komut dosyasını çalıştırırsa, farklı bir ad alırlar" demek gerçekten mantıklıdır.


5

$$ PID'nizdir. Dikkatli olmadıkça ve başka hiç kimse tam olarak aynı şekilde yapmadığı sürece benzersiz bir dosya adı oluşturmaz.

Genellikle / tmp / programım $$ gibi bir şey yaratırsınız

Bunu kırmanın pek çok yolu var ve diğer insanların yazabileceği yerlere yazıyorsanız, birçok OS'de hangi PID'ye sahip olacağınızı tahmin edip vidalayacağınızı tahmin etmek zor değil - koştuğunuzu hayal edin root olarak ve / etc / passwd'yi işaret eden bir sembolik bağlantı olarak / tmp / yourprogname13395 oluşturuyorum ve içine yazıyorsunuz.

Bu bir kabuk betiğinde yapmak kötü bir şeydir. Bir şey için geçici bir dosya kullanacaksanız, en azından dosyayı açmak (oluşturmak) için "özel" bayrağını eklemenize izin verecek daha iyi bir dil kullanmalısınız. O zaman başka bir şey ıslatmadığınızdan emin olabilirsiniz.


3

$$, geçerli kabuk işleminin pididir. Benzersiz dosya adları oluşturmak için iyi bir yol değildir.


3

$$, betiğinizi çalıştıran kabuk yorumlayıcısının pid (işlem kimliği) 'dir. Şu anda bir sistemde çalışan her işlem için farklıdır, ancak zaman içinde pid etrafına sarılır ve çıktıktan sonra sonunda aynı pid ile başka bir işlem olacaktır.Çalıştığınız sürece pid size özeldir.

Yukarıdaki tanımdan, bir komut dosyasında $$'yi kaç kez kullanırsanız kullanın, aynı sayıyı döndüreceği açık olmalıdır.

Son derece güvenilir veya güvenli olması gerekmeyen şeyler için geçici dosyanız olarak örneğin /tmp/myscript.scratch.$$ kullanabilirsiniz. Örneğin, trap komutunu kullanarak, komut dosyanızın sonunda bu tür geçici dosyaları silmek iyi bir uygulamadır:

trap "echo 'Cleanup in progress'; rm -r $TMP_DIR" EXIT

2

Bu, bash işleminin işlem kimliğidir. Hiçbir eşzamanlı işlem aynı PID'ye sahip olmayacaktır.


2

$$, betiğinizin çalıştığı kabuğun işlem kimliğidir. Daha fazla bilgi için sh veya bash kılavuz sayfasına bakınız. Man sayfaları ya "man sh" komut satırı kullanılarak ya da web'de "shell manpage" için arama yapılarak bulunabilir


2

İkinci emk'in cevabını vereyim - $$ 'yi "benzersiz" bir şey olarak kullanmayın. Dosyalar için mktemp kullanın. Aynı bash betiğindeki diğer kimlikler için, oldukça iyi bir benzersizlik şansı için "$$$ (tarih +% s% N)" kullanın .

 -k

0

Ayrıca, bu komut ile giriş kullanıcı adını alabilirsiniz. Örneğin.

echo $(</proc/$$/login id). After that, you need to use getent command.
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.