मैं एक परिवर्तनीय सूची को स्रोत करने का प्रयास कर रहा हूं जो बैश में एक एकल चर में पॉप्युलेट किया गया है।

मैं फिर इस एकल चर को स्क्रिप्ट के लिए उपलब्ध चर की सामग्री (जो अन्य चर हैं) को स्रोत बनाना चाहता हूं।

मैं sqlplus फ़ाइल को स्पूल किए बिना इसे प्राप्त करना चाहता हूं, फिर इस फ़ाइल को स्रोत करें (यह पहले से ही काम करता है जैसा मैंने कोशिश की थी)।

कृपया नीचे देखें कि मैं क्या कोशिश कर रहा हूं:

#!/bin/bash

var_list=$(sqlplus -S /@mydatabase << EOF
set pagesize 0
set trimspool on
set headsep off
set echo off
set feedback off
set linesize 1000
set verify off
set termout off
select varlist from table;
EOF
)

#This already works when I echo any variable from the list
#echo "$var_list" > var_list.dat
#. var_list.dat
#echo "$var1, $var2, $var3"

#Im trying to achieve the following
. $(echo "var_list")
echo "$any_variable_from_var_list"

डेटाबेस से var_list की सामग्री इस प्रकार है:

var1="Test1"
var2="Test2"
var3="Test3"

मैंने इसे अन्य तरीकों से सोर्सिंग करने का भी प्रयास किया जैसे:

. <<< $(echo "$var_list")
. $(cat "$var_list")

मुझे यकीन नहीं है कि मुझे थोड़ी देर के लूप का उपयोग करके अब प्रत्येक पंक्ति में पढ़ने की ज़रूरत है।

किसी भी सलाह की सराहना की जाती है।

1
Ali E 19 मार्च 2020, 21:32

2 जवाब

सबसे बढ़िया उत्तर

आप ऐसा कर सकते हैं:

. /dev/stdin <<<"$varlist"

<<< यहां एक स्ट्रिंग है। यह <<< के पीछे डेटा की सामग्री को मानक इनपुट पर पुनर्निर्देशित करता है।

/dev/stdin मानक इनपुट का प्रतिनिधित्व करता है। तो 0 फ़ाइल डिस्क्रिप्टर से पढ़ना /dev/stdin खोलने और परिणामी फ़ाइल डिस्क्रिप्टर पर read() को कॉल करने जैसा है।

क्योंकि source कमांड को एक फ़ाइल नाम की आवश्यकता होती है, हम इसे पास करते हैं /dev/stdin और डेटा को मानक इनपुट पर पढ़ने के लिए रीडायरेक्ट करते हैं। इस तरह source मानक इनपुट से कमांड को यह सोचकर पढ़ता है कि यह फ़ाइल से पढ़ रहा है, जबकि हम अपना डेटा उस इनपुट में पास करते हैं जिसे हम पास करना चाहते हैं।

फ़ाइल की अपेक्षा रखने वाले टूल के लिए /dev/stdin का उपयोग करना काफी सामान्य है। मुझे नहीं पता कि क्या संदर्भ देना है, मैं लिंक करूंगा: यहां बैश मैनुअल स्ट्रिंग्स, Posix 7 बेस डेफिनिशन 2.1.1p4 लास्ट बुलेट पॉइंट, linux कर्नेल प्रलेखन /dev पर / निर्देशिका संपूर्ण, बैश मैनुअल शेल बिलिन्स, शायद C99 7.19. 3p7.

2
KamilCuk 20 मार्च 2020, 01:13
1
हालांकि यह कोड प्रश्न को हल कर सकता है, एक स्पष्टीकरण सहित यह समस्या कैसे और क्यों हल करता है, वास्तव में आपकी गुणवत्ता में सुधार करने में मदद करेगा पोस्ट, और शायद अधिक अप-वोट में परिणाम। याद रखें कि आप भविष्य में पाठकों के लिए प्रश्न का उत्तर दे रहे हैं, न कि केवल उस व्यक्ति के लिए जो अभी पूछ रहा है। स्पष्टीकरण जोड़ने के लिए कृपया अपने उत्तर को संपादित करें करें और संकेत दें कि कौन सी सीमाएं और धारणाएं लागू होती हैं।
 – 
Adrian Mole
19 मार्च 2020, 23:41
कृपया बताएं कि यह क्यों काम करेगा, शायद इस संदर्भ में कि मैं इसके बारे में और कहां पढ़ सकता हूं?
 – 
Ali E
19 मार्च 2020, 23:47
यह आंशिक रूप से काम करता है। दुर्भाग्य से यह उन मामलों पर काम नहीं करता है जहां उदाहरण के लिए var1 मल्टीलाइन है: var1="Test1 Test2" कोई विचार?
 – 
Ali E
20 मार्च 2020, 13:18
ठीक है अब यह काम करता है, मुझे नहीं पता था कि मैं अभी भी stdin <<< $(echo "$varlist" का उपयोग कर रहा था। आपकी मदद के लिए बहुत बहुत धन्यवाद!
 – 
Ali E
20 मार्च 2020, 14:31

मुझे स्थानीय रूप से फ़ाइलों में dotenv मानों को संग्रहीत करने और DevOps पाइपलाइनों के लिए vars की आवश्यकता थी, इसलिए मैं मांग पर रनटाइम पर्यावरण के लिए स्रोत कर सकता था (फ़ाइल से उपलब्ध होने पर और vars जब नहीं)। हालांकि, मुझे अलग-अलग संस्करणों में अलग-अलग डॉटनव सेट स्टोर करने और स्रोत शाखा के आधार पर उनका उपयोग करने की आवश्यकता थी (जिसे मैं .gitlab-ci.yml में export ENV=${CI_COMMIT_BRANCH:=develop} के माध्यम से $ENV में लोड करता हूं)। इसके साथ मेरे पास डेवलपमेंटएनवी, क्यूएएनवी, और प्रोडक्शनएनवी होंगे, प्रत्येक एक var होगा जिसमें इसकी उपयुक्त डॉटनव सामग्री होगी (स्पष्ट होने के लिए अनावश्यक होना।)

unset FOO; # Clear so we can confirm loading after
ENV=develop; # 

developEnv="VERSION=1.2.3
FOO=bar"; # Creating a simple dotenv in a var, with linebreak (as the files passed through will have)

envVarName=${ENV}Env # Our dynamic var-name
source <(cat <<< "${!envVarName}") # Using the dynamic name, 
echo $FOO;
# bar
0
rainabba 7 मई 2021, 02:52