bash: Salt okunur bir kök bölümde okuma <<< “$ VARIABLE” kullanırken bazı sorunlar. Bilinen herhangi bir geçici çözüm var mı?


11

Tesadüf eseri ATA-ID-to-device-name betiğimi kullanmak zorunda kaldım (burada bulunur: /server/244944/linux-ata-errors-translating-to-a-device-name/ 426561 # 426561 ) salt okunur bir / bölümde. Merak ediyorsanız, /bölümünüze erişmenizi sağlayan , ancak varsayılan olarak salt okunur olarak bağlayacak bir Ubuntu kurtarma konsoluydu . Bu konuda memnunum, çünkü aksi takdirde muhtemelen betiğimin belirli bir satırdan dolayı bir R / O sisteminde garip bir şekilde davrandığını öğrenemezdim:

IFS=: read HostMain HostMid HostSub <<< "$HostFull"

Bu mu değil hiçbir yazma izni olup olmadığını çalışır. Yine de başarısız olacağını varsaymazdım. Ama görünüşe göre <<<operatör yok yere bazı geçici dosyayı yazmaya gerektirir.

Ancak geçici bir dosyanın oluşturulmasını atlatmanın herhangi bir yolu var mı, yoksa dosyanın nereye yazıldığını belirtmenin bir yolu var mı? Ubuntu kurtarma konsolunda, /rundizinde --- garip bir şekilde --- yazma izni var , bu yüzden bir şekilde readgeçici dosyayı her zamankinden başka bir yere yazmayı "söyleyebilseydim" olurdu .


2
@gniourf_gniourf Hayır, “bir dosya tanımlayıcısının açılması” sorun olmaz (neden?) ve /dev/fdbununla hiçbir ilgisi yoktur. <<<ancak suçludur, çünkü geçici bir dosya oluşturur (bir yere yazılması gerekir).
Gilles 'SO- kötü olmayı kes

Yanıtlar:


8

Bir dizi, geçici bir dosyaya gerek olmadan dizenin ayrıştırılmasını sağlayabilir. Globbing'i kapatmayı unutmayın.

set -f
IFS=: Hosts=($HostFull)
HostMain=${Hosts[0]}
HostMid=${Hosts[1]}
HostSub=${Hosts[2]}
set +f

2
hatta olmadan IFS, emin içinde boşluk olmadığından eğer $HostFullböylece: Hosts=( ${HostFull//:/ } ). Veya boşluklar olsa bile: HostMain=${HostFull%%:*}; HostMid=${HostFull#*:}; HostSub=${HostMid#*:}; HostMid=${HostMid%:*}(ya da benzer bir şey, kafam karışıyor :D).
gniourf_gniourf

Haklısınız, parametre genişlemesinin zor iş olduğunu gösterdiğiniz gibi ...
xae

4

@Gniourf_gniourf, muhtemelen yazma erişimine ihtiyacınız var ama dosya tanımlayıcılarına değil, büyük olasılıkla bir dosyaya katılıyorum.

Bunu salt okunur bölümdeyken komutunuzun yürütülmesini izleyerek test edebilirsiniz.

{ strace -p "$$" & sleep 1; read var1 <<< "hi"; sleep 1; kill "$1"; }

Yukarıdakiler straceBash kabuğunda (işlem $$) çalışacaktır . Sonra 1 saniye uyur ve sonra readHERE STRING'den çalışır . İpi "hi"bu konuma koydum . Sonra sleepdaha ikincisi ve daha sonra da .killstrace

Misal

Bu çıktıyı ayrıştırırken bir dosya olarak açıldığını fark edeceksiniz O_WRONLY, bu da bir dosyaya yazmak içindir.

open("/tmp/sh-thd-4137571604", O_WRONLY|O_CREAT|O_EXCL|O_TRUNC, 0600) = 3

Yukarıda komut diziniz tarafından hangi dosyanın yazıldığını görebiliriz.


1
“Dosya tanımlayıcıları oluşturmak” için değil (bu bir anlam ifade etmiyor). Dosya oluşturmak için . O değil readyazmak üzere bir dosya (yani saçma olurdu) açılır, bu kadar <<<.
Gilles 'SO- kötü olmayı kes

@Gilles - teşekkürler, bana ne söylediğini tam olarak anlamadım. A. kadar temizlenen
slm

Çok teşekkür ederim! Gelecekte benzer konularda bana defalarca yardımcı olabilecek çok güzel bir teknik. Ancak bir şey olduğunu bana endişe ve bu gerçektir /tmpbir olan kodlanmış yolu. Ve muhtemelen, bunu tahmin ettik /tmp IS zaten orada, ancak salt okunur de! Ve bu kurtarma konsolu üzerinde çalışmak beni canlı dosya sistemime giriş yapacak çünkü, symlinking veya herhangi bir şey (o konsolda iken bile) karışıklık istemem.
sözdizimi

3

Bu tür görevler için konumsal parametreleri çok kullanışlı buluyorum. Genellikle tüm kabuklara taşınabilir ve çatal veya geçici dosya maliyeti yoktur.

$ HostFull=main:mid:sub    
$ oldIFS=$IFS; IFS=:; set -- $HostFull; IFS=$oldIFS
$ echo $1
main
$ echo $2
mid
$ echo $3
sub

İyi bir yaklaşım! Teşekkür ederim. Ayrıca, herhangi bir harici araç gerektirmediğini seviyorum (genellikle bu kısıtlı ortamlarda herhangi bir şekilde bulmamız beklenmiyor). Tek şey olabilir bazı sorunlara yol olduğunu $1, $2, $3malzeme: Bir komut unutmayın bu genellikle komut geçirilen bir tartışma için duracak kendisi . - Ve biz oradayken: IFS'nin boşluk olması gerekiyorsa, * IFS = * bu sözdiziminde çalışmaz; açıkça IFS = '' belirtmeniz gerekecektir .
sözdizimi
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.