bash: पढ़ने के लिए <<< "$ VARIABLE" का उपयोग करते समय कुछ समस्या केवल रूट विभाजन पर। किसी भी ज्ञात workarounds?


11

संयोग से मुझे अपनी ATA-ID-to-device-name स्क्रिप्ट (यहाँ मिली: /server/244944/linux-ata-errors-translating-to-a-device-name/ का उपयोग करना पड़ा 426561 # 426561 ) केवल पढ़ने के लिए / विभाजन पर। यदि आप उत्सुक हैं, तो यह एक उबंटू रिकवरी कंसोल था जो आपको अपने /विभाजन तक पहुंचने देगा, लेकिन इसे केवल डिफ़ॉल्ट रूप से रीड-ओनली माउंट करेगा। मुझे इस बारे में खुशी है, क्योंकि अन्यथा मुझे शायद कभी नहीं पता चला कि मेरी स्क्रिप्ट एक विशिष्ट रेखा के कारण आर / ओ प्रणाली पर अजीब व्यवहार करती है, यह एक:

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

यदि लिखित अनुमति नहीं है तो यह काम नहीं करता है। मुझे लगता है कि यह विफल होता है, हालांकि नहीं होता। लेकिन जाहिरा तौर पर <<<ऑपरेटर है कहीं न कहीं कुछ अस्थायी फ़ाइल लिखने के लिए आवश्यकता होती है।

लेकिन क्या किसी अस्थायी फ़ाइल के निर्माण को दरकिनार करने का कोई तरीका है, या, यह निर्दिष्ट करने का कोई तरीका है कि फ़ाइल को कहाँ लिखा गया है? उबंटू रिकवरी कंसोल में, वहाँ --- अजीब तरह से पर्याप्त है --- /runनिर्देशिका पर अनुमति लिखें , ताकि मैं किसी भी तरह readसे अस्थायी फ़ाइल लिखने के लिए "बता" सकूं।


2
@gniourf_gniourf नहीं, "फ़ाइल डिस्क्रिप्टर खोलने" से कोई समस्या नहीं होगी (ऐसा क्यों?); और /dev/fdइससे कोई लेना-देना नहीं है। <<<हालांकि अपराधी है, क्योंकि यह एक अस्थायी फ़ाइल बनाता है (जिसे कहीं लिखा जाना चाहिए)।
गिल्स एसओ-

जवाबों:


8

एक सरणी एक अस्थायी फ़ाइल की आवश्यकता के बिना स्ट्रिंग को पार्स कर सकती है। ग्लोबिंग को बंद करना न भूलें।

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

2
या यहां तक कि बिना IFS, यदि आप सुनिश्चित कर रहे हैं वहाँ में स्पेस नहीं $HostFullइतनी के रूप में: Hosts=( ${HostFull//:/ } )। या यहां तक ​​कि अगर वहाँ रिक्त स्थान हैं: HostMain=${HostFull%%:*}; HostMid=${HostFull#*:}; HostSub=${HostMid#*:}; HostMid=${HostMid%:*}(या कुछ इसी तरह, मैं भ्रमित हो रहा हूं :D)।
gnourf_gniourf

आप सही हैं, जैसा कि आप दिखाते हैं कि पैरामीटर विस्तार मुश्किल बूसी है ...
xae

4

मैं @gniourf_gniourf से सहमत हूं, आपकी संभवतः लिखने की जरूरत है, लेकिन फाइल डिस्क्रिप्टर तक नहीं, सबसे अधिक संभावना एक फाइल की है।

जब आप आसानी से विभाजन में अपनी कमांड के निष्पादन को ट्रेस करके यह परीक्षण कर सकते हैं।

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

ऊपर straceबैश शेल (प्रक्रिया $$) पर चलेगा । यह तब 1 सेकंड के लिए सोता है, और फिर readHERE STRING से चलता है । मैंने स्ट्रिंग "hi"को इस स्थिति में रखा है । मैं तो sleepएक और दूसरी और उसके बाद के लिए ।killstrace

उदाहरण

इस आउटपुट को पार्स करते समय आप देखेंगे कि एक फ़ाइल के रूप में खोला गया है O_WRONLY, जो एक फ़ाइल में लिखने के लिए है।

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

ऊपर हम देख सकते हैं कि आपके कमांड अनुक्रम द्वारा किस फ़ाइल को लिखा जा रहा है।


1
"फ़ाइल डिस्क्रिप्टर बनाने के लिए नहीं" (इसका कोई मतलब नहीं है)। फ़ाइल बनाने के लिए । ऐसा नहीं है readकि लिखने के लिए एक फ़ाइल खुलती है (यह मूर्खतापूर्ण होगा), यह है <<<
गिल्स एसओ-

@ गिल्स - धन्यवाद, मुझे यह समझ में नहीं आया कि यह मुझे क्या बता रहा है।
slm

आपका बहुत बहुत धन्यवाद! एक बहुत अच्छी तकनीक, जो भविष्य में इसी तरह के मुद्दों के साथ कई बार मेरी मदद कर सकती है। हालांकि, एक बात है मुझे चिंता है, और उस तथ्य यह है कि है /tmpएक है हार्डकोडेड पथ। और शायद आपने यही अनुमान लगाया गया है, /tmp है वहाँ पहले से ही है, लेकिन केवल पढ़ने के रूप में अच्छी तरह! और उस रिकवरी कंसोल पर काम करने के बाद से मुझे अपने लाइव फाइल सिस्टम में लॉग इन करना होगा, मैं सिम्क्लिंग या जो कुछ भी (उस कंसोल में रहते हुए भी नहीं) वहां गड़बड़ नहीं करना चाहूंगा।
वाक्य रचना

3

मुझे इस तरह के कार्य के लिए स्थितिगत पैरामीटर बहुत उपयोगी लगते हैं। यह आमतौर पर सभी गोले के लिए पोर्टेबल है, और न ही कांटे और न ही अस्थायी फ़ाइलों की लागत होती है।

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

एक अच्छा तरीका! धन्यवाद। इसके अलावा, मुझे यह पसंद है कि इसे किसी भी बाहरी उपकरण की आवश्यकता नहीं है (कि हम आम तौर पर उन प्रतिबंधित वातावरणों में किसी भी तरह से खोजने की उम्मीद नहीं करते हैं)। केवल बात यह है कि हो सकता है कुछ परेशानी का कारण है $1, $2, $3सामान: याद रखें कि एक स्क्रिप्ट में, यह आम तौर पर एक बहस स्क्रिप्ट के लिए पारित करने के लिए खड़े होंगे ही । - और जब तक हम इस पर हैं: यदि IFS का अर्थ अंतरिक्ष है, तो * IFS = * इस सिंटैक्स में नहीं होगा; आपको स्पष्ट रूप से IFS = '' निर्दिष्ट करना होगा ।
वाक्यविन्यास
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.